3. Delete, search and print linked list nodes
Tip: after the article is written, the directory can be generated automatically. Please refer to the help document on the right for how to generate it
preface
Purpose: generate multiple frequency divisions through a timer. For example, analog timers A and a have name, input, output, aim, now, task pointer and other information. When an interrupt comes, if input==1, the current value now increases automatically, and when now==aim, output=1 is generated. The simulated timer is hung on the linked list and can be deleted at any time.
Tip: the following is the main content of this article. The following cases can be used for reference
I Basic data structure?
The first is the structure diagram of the timer
Then is the structure diagram of nodes and linked lists
code implementation
typedef struct Tcreate { u32 now ; u32 aim; //0-65535 u8 input; u8 output; u8 num; //Up to 256 void(*task)(void); //The return value is void, and the entry parameter is a function pointer of void type }timepack; //Timer data structure 16 bytes Memory problems
Where num stands for name or priority.
And the structure of linked list nodes
typedef struct Node { timepack *data_point; struct Node *next; }Time_node; //Timer node
2, Create a list C piece
1. Initialize the header node
Time_node *headnode=NULL; bool headnode_init() //Node initialization { headnode=(Time_node*)malloc(sizeof(Time_node));//Request memory if(headnode==NULL)return false; headnode->next=NULL; return true; }
2. Adding linked list nodes
Traverse the linked list until it points to null, apply for memory of timenode and memory of timepack.
copy the data indicated by the pointer of the tiamepack to the area indicated by the pointer in the data field of the new node. (compare winding)
bool add_timer(timepack *data) //Add frequency division clock { Time_node *p=headnode; while(p->next!=NULL) //Traverse until the pointer field of p points to NULL { p=p->next; } p->next=(Time_node*)malloc(sizeof(Time_node));//Request node memory if(p->next==NULL)return false; p=p->next; p->data_point=(timepack*)malloc(sizeof(timepack));//Request node packet memory if(p->data_point==NULL) { free(p); //Release the space opened up return false; } memcpy(p->data_point,data,sizeof(timepack)); p->next=NULL; return true; }
3. Delete, search and print linked list nodes
bool delete_timer(u8 name) //Delete node number name { bool res=false; Time_node *p=headnode; while(p->next!=NULL) { Time_node *Temp=p; p=p->next; if(p->data_point->num==name) { Temp->next=p->next; free(p->data_point); //Release the memory pointed by the pointer and the memory pointed by p in the data field pointed by p p->data_point=NULL; //Avoid generating wild pointers free(p); p=Temp; res=true; } } return res; }
Find the function. Note that the return value is the data of a node pointer type
Time_node* search_timer(u8 name) //Find the pointer of the node corresponding to name { //You can access the data of the corresponding name Time_node *p=headnode; while((p->next!=NULL)&&(p->data_point->num!=name)) { p=p->next; } if(p->data_point->num!=name)p=NULL; //Determine whether name exists return p; }
u8 print_all() //Traverse and print all nodes and get the total number of nodes { u8 i=0; Time_node*p=headnode; printf("------------begin----------------"); printf("\r\n"); while(p->next!=NULL) { p=p->next; i++; printf("i=%d\r\n",i); printf("aim=%d\r\n",p->data_point->aim); printf("num=%d\r\n",p->data_point->num); } printf("-------------end--------------"); printf("\r\n"); return i; }
III Object oriented thinking
I didn't have the consciousness of process and object at all before. I know that after reading the list explanation of station B up, I really have a feeling of enlightenment https://www.bilibili.com/video/BV1BE411h7kG?share_source=copy_web
Improved code
Perform task operations on all nodes after the current node. The task is set by itself, such as the data set as the printf node. Then traverlist is a print function, the same as the printf all function above. But! We can set the task to other (such as oled display), so traverlist can display all nodes after the current one. There is no need to write a show all function, which is very convenient.
//The entry parameter points to the pointer of the current node, and the entry parameter with null return value is the function pointer of the node pointer void traverlist(Time_node *nowpoint,void(*task)(Time_node *point)) { Time_node *ptemp=nowpoint; while(ptemp!=NULL) { task(ptemp); ptemp=ptemp->next; } }
Add the remaining code
//The priority is in the order of name's size. The card with the smaller name is in the front bool add_timer2(timepack *data) { Time_node *p=headnode; Time_node *temp; while((p->next->data_point->num<=data->num)&&(p->next!=NULL)) { p=p->next; } temp=p->next; p->next=(Time_node*)malloc(sizeof(Time_node));//Request node memory if(p->next==NULL)return false; p=p->next; p->data_point=(timepack*)malloc(sizeof(timepack));//Request node data structure memory if(p->data_point==NULL) { free(p); //Release the space opened up return false; } memcpy(p->data_point,data,sizeof(timepack)); p->next=temp; return true; }
Finally, learn the stm32 library function and encapsulate it.
//Mode 0 in order 1 by name from small to large priority from high to low void include_time(u32 Now,u32 Aim,u8 Num,void(*work)(void),u8 mode) //encapsulation { timepack timestruct; timestruct.aim=Aim; timestruct.now=Now; timestruct.num=Num; timestruct.input=1; timestruct.output=0; timestruct.task=work; if(mode==0)add_timer(×truct); else add_timer2(×truct); }
IV realization
Timer III is adopted
void TIM3_IRQHandler(void) //TIM3 interrupt { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //Check whether the specified TIM interrupt occurs: TIM interrupt source { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //Clear the interrupt pending bit of TIMx: TIM interrupt source time_handle(); } }
void time_handle() //timer interrupt { Time_node *p=headnode; //Define header pointer p=p->next; while(p) { if((p->data_point->input==1)&&(p->data_point->output==0))//out is equivalent to the interrupt flag bit { p->data_point->now++; if(p->data_point->now>=p->data_point->aim)//Timer overflow { p->data_point->output=1; p->data_point->now=0; //How to generate an interrupt? deal_task(p); } } else if(p->data_point->input==0)delete_timer(p->data_point->num); p=p->next; } } //Timer processing task void deal_task(Time_node *point) { if(point->data_point->output==1) { point->data_point->task(); //implement point->data_point->output=0; } }
void timer_init() { include_time(0,100,36,work36,0); include_time(0,200,37,work37,0); include_time(0,300,22,work22,0); include_time(0,400,24,work24,0); include_time(0,10,44,work44,0); //include encapsulation function include_time(0,500,11,work11,1); }
work randomly sets up a few time-consuming tasks because they are carried out in interruption....
int main(void) { int a,b,len; Time_node* datapack; delay_init(); //Delay function initialization uart_init(9600); //The serial port is initialized to 9600 LED_Init(); //Initialize the hardware interface to the LED LCD_Init(); headnode_init(); //Global first node initialization timer_init(); //Be sure to put it behind the first node POINT_COLOR=RED; LCD_Clear(WHITE); TIM3_Int_Init(500,7200); //Total clock timer 0.05s POINT_COLOR=RED; LCD_ShowString(30,20,200,24,24,"Mini STM32 ^_^"); delete_timer(22); //Delete specified name while(1) { a=sizeof(timepack); //Data byte length LCD_ShowNum(30,60,a,2,24); b=sizeof(Time_node); //Node byte length LCD_ShowNum(60,60,b,2,24); // len=print_all(); // Print all data datapack=search_timer(24); //Find the address of the corresponding node of the data with the specified name LCD_ShowNum(30,140,search_timer(36)->data_point->now,3,24); LCD_ShowNum(100,140,search_timer(36)->data_point->aim,3,24); LCD_ShowNum(170,140,search_timer(36)->data_point->output,3,24); LCD_ShowNum(30,180,search_timer(37)->data_point->now,3,24); LCD_ShowNum(100,180,search_timer(37)->data_point->aim,3,24); LCD_ShowNum(170,180,search_timer(37)->data_point->output,3,24); LCD_ShowNum(30,220,datapack->data_point->now,3,24); LCD_ShowNum(100,220,datapack->data_point->aim,3,24); LCD_ShowNum(170,220,datapack->data_point->output,3,24); LCD_ShowNum(30,260,search_timer(11)->data_point->now,3,24); LCD_ShowNum(100,260,search_timer(11)->data_point->aim,3,24); LCD_ShowNum(170,260,search_timer(11)->data_point->output,3,24); traverlist(search_timer(11),showdata); //Traverse the nodes after the current node and execute the showdata function } }
V effect
I've seen RTOS in recent days. I plan not to execute tasks in interrupts, but in the main function. Interrupts only select the one with the highest priority, which means scheduling.
summary
I've seen RTOS in recent days. I plan not to execute tasks in interrupts, but in the main function. Interrupts only select the one with the highest priority, which means scheduling.