打印
[应用相关]

环形队列

[复制链接]
604|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
关于串口发送数据,自己以前呢是这样

voidUsart_Out_Char(unsignedchar*c,uint32_t cnt)

{while(cnt--)

{

USART_SendData(USART1,*c++);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) ==RESET );

}

}
作者:杨奉武
链接:https://www.jianshu.com/p/d4010ef2140f
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

使用特权

评论回复
沙发
operating|  楼主 | 2020-7-23 20:29 | 只看该作者
下面的调用方式

uint8_t aaa[1024]={1,2,3,42,0};intmain(void)

{

NVIC_Configuration();

Led_Gpio_Init();

Timer2_Config();

uart_init(115200);//串口初始化为115200while(1)

{

Usart_Out_Char(aaa,1024);

delay_ms(1000);

PFout(6) = ~PFout(6);

}

}

使用特权

评论回复
板凳
operating|  楼主 | 2020-7-23 20:30 | 只看该作者
当发送数据的时候,会一直在调用此函数的地方等着,,,,,,直至发送完所有的数据,要知道用串口中断发送数据要比这样发送快的多.......瞎耽误时间

使用特权

评论回复
地板
operating|  楼主 | 2020-7-23 20:31 | 只看该作者
假设现在我用中断发送

假设没有缓冲区

voidUsartOutChar(unsignedchar*Buff,uint32_t cnt)

{

dat=Buff;//把发送地址给dat

BuffCnt=cnt;//记录发送的个数

USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//打开发送中断

}

使用特权

评论回复
5
operating|  楼主 | 2020-7-23 20:32 | 只看该作者
voidUSART1_IRQHandler(void)//串口1中断服务程序{

u8 Res;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//接收中断(接收到的数据必须是0x0d 0x0a结尾){

Res=USART_ReceiveData(USART1);//读取接收到的数据}if(USART_GetITStatus(USART1, USART_IT_TXE) !=RESET)//发送中断

{if(BuffCnt--)

{

USART_SendData(USART1,*dat);//发送数据

dat++;

}else{//发送字节结束USART_ClearITPendingBit(USART1,USART_IT_TXE);

USART_ITConfig(USART1, USART_IT_TXE, DISABLE);

USART_ITConfig(USART1, USART_IT_TC, ENABLE);

}

}//发送完成if(USART_GetITStatus(USART1, USART_IT_TC) !=RESET)

{

USART_ClearITPendingBit(USART1,USART_IT_TC);

USART_ITConfig(USART1, USART_IT_TC, DISABLE);

}

}

使用特权

评论回复
6
operating|  楼主 | 2020-7-23 20:32 | 只看该作者
uint8_t aaa[1024]={1,2,3,42,0};intmain(void)

{

NVIC_Configuration();

Led_Gpio_Init();

Timer2_Config();

uart_init(115200);//串口初始化为115200while(1)

{

UsartOutChar(aaa,10);delay_ms(10);}

}

使用特权

评论回复
7
operating|  楼主 | 2020-7-23 20:33 | 只看该作者
加一个缓冲区---假设是下面这样子,中断发送的数据从这个缓冲区里面取

使用特权

评论回复
8
operating|  楼主 | 2020-7-23 20:34 | 只看该作者
然后呢,接着又填入了

使用特权

评论回复
9
operating|  楼主 | 2020-7-23 20:34 | 只看该作者
接着

使用特权

评论回复
10
operating|  楼主 | 2020-7-23 20:35 | 只看该作者
假设我又想添加数据,可是呢后面空的那一块数据空间不够了......要是能把数组的尾和头联系起来就好啦......

假设加满了,,,如果能自动的加到前面就好啦.....

使用特权

评论回复
11
operating|  楼主 | 2020-7-23 20:36 | 只看该作者
下面是实现程序--实现程序是自己想学Esp8266连接机智云的时候无意中看到的,,,,,记得 天鲁哥 曾经说过环形队列实现的很巧妙,,,改天有空再研究下当初天鲁哥给的程序

使用特权

评论回复
12
operating|  楼主 | 2020-7-23 20:37 | 只看该作者
往里面加数据尾指针向右增加...加到头回到首地址

从里面读数据头指针向右增加...加到头回到首地址

使用特权

评论回复
13
operating|  楼主 | 2020-7-23 20:37 | 只看该作者
注意

使用特权

评论回复
14
operating|  楼主 | 2020-7-23 20:38 | 只看该作者
还是在唠叨唠叨





使用特权

评论回复
15
operating|  楼主 | 2020-7-23 20:39 | 只看该作者
rb_t pRb;///< 环形缓冲区结构体变量uint8_t rbBuf[RB_MAX_LEN];///< 环形缓冲区数据缓存区voidrbCreate(rb_t* rb,u8 *Buff,uint32_t BuffLen)//创建或者说初始化环形缓冲区{if(NULL ==rb)

{

printf("ERROR: input rb is NULL\n");return;

}

rb->rbCapacity =BuffLen;

rb->rbBuff =Buff;

rb->rbHead = rb->rbBuff;//头指向数组首地址rb->rbTail = rb->rbBuff;//尾指向数组首地址}voidrbDelete(rb_t* rb)//删除一个环形缓冲区{if(NULL ==rb)

{

printf("ERROR: input rb is NULL\n");return;

}

rb->rbBuff = NULL;//地址赋值为空rb->rbHead = NULL;//头地址为空rb->rbTail = NULL;//尾地址尾空rb->rbCapacity =0;//长度为空}

使用特权

评论回复
16
operating|  楼主 | 2020-7-23 20:40 | 只看该作者
int32_t rbCapacity(rb_t*rb)//获取链表的长度{if(NULL ==rb)

{

printf("ERROR: input rb is NULL\n");return-1;

}returnrb->rbCapacity;

}

使用特权

评论回复
17
operating|  楼主 | 2020-7-23 20:41 | 只看该作者
int32_t rbCanRead(rb_t*rb)//返回能读的空间{if(NULL ==rb)

{

printf("ERROR: input rb is NULL\n");return-1;

}if(rb->rbHead == rb->rbTail)//头与尾相遇{return0;

}if(rb->rbHead < rb->rbTail)//尾大于头{returnrb->rbTail - rb->rbHead;

}returnrbCapacity(rb) - (rb->rbHead - rb->rbTail);//头大于尾}

使用特权

评论回复
18
operating|  楼主 | 2020-7-23 20:42 | 只看该作者
int32_t rbCanWrite(rb_t*rb)//返回能写入的空间{if(NULL ==rb)

{

printf("ERROR: input rb is NULL\n");return-1;

}returnrbCapacity(rb) - rbCanRead(rb);//总的减去已经写入的空间}/*rb--要读的环形链表

data--读出的数据

count--读的个数*/int32_t rbRead(rb_t*rb,void*data, size_t count)

{intcopySz =0;if(NULL ==rb)

{

printf("ERROR: input rb is NULL\n");return-1;

}if(NULL ==data)

{

printf("ERROR: input data is NULL\n");return-1;

}if(rb->rbHead < rb->rbTail)//尾大于头{

copySz= min(count, rbCanRead(rb));//查看能读的个数memcpy(data, rb->rbHead, copySz);//读出数据到datarb->rbHead += copySz;//头指针加上读取的个数returncopySz;//返回读取的个数}else//头大于等于了尾{if(count < rbCapacity(rb)-(rb->rbHead - rb->rbBuff))//读的个数小于头上面的数据量{

copySz= count;//读出的个数memcpy(data, rb->rbHead, copySz);//rb->rbHead +=copySz;returncopySz;

}else//读的个数大于头上面的数据量{

copySz= rbCapacity(rb) - (rb->rbHead - rb->rbBuff);//先读出来头上面的数据memcpy(data, rb->rbHead, copySz);

rb->rbHead = rb->rbBuff;//头指针指向数组的首地址//还要读的个数copySz += rbRead(rb, (char*)data+copySz, count-copySz);//接着读剩余要读的个数returncopySz;

}

}

}

使用特权

评论回复
19
operating|  楼主 | 2020-7-23 20:43 | 只看该作者
int32_t rbWrite(rb_t*rb,constvoid*data, size_t count)

{inttailAvailSz =0;if(NULL ==rb)

{

printf("ERROR: rb is empty \n");return-1;

}if(NULL ==data)

{

printf("ERROR: data is empty \n");return-1;

}if(count >= rbCanWrite(rb))//如果剩余的空间不够{

printf("ERROR: no memory \n");return-1;

}if(rb->rbHead <= rb->rbTail)//头小于等于尾{

tailAvailSz= rbCapacity(rb) - (rb->rbTail - rb->rbBuff);//查看尾上面剩余的空间if(count <= tailAvailSz)//个数小于等于尾上面剩余的空间{

memcpy(rb->rbTail, data, count);//拷贝数据到环形数组rb->rbTail += count;//尾指针加上数据个数if(rb->rbTail == rb->rbBuff+rbCapacity(rb))//正好写到最后{

rb->rbTail = rb->rbBuff;//尾指向数组的首地址}returncount;//返回写入的数据个数}else{

memcpy(rb->rbTail, data, tailAvailSz);//填入尾上面剩余的空间rb->rbTail = rb->rbBuff;//尾指针指向数组首地址//剩余空间                  剩余数据的首地址      剩余数据的个数returntailAvailSz + rbWrite(rb, (char*)data+tailAvailSz, count-tailAvailSz);//接着写剩余的数据}

}else//头大于尾{

memcpy(rb->rbTail, data, count);

rb->rbTail +=count;returncount;

}

}

使用特权

评论回复
20
operating|  楼主 | 2020-7-23 20:44 | 只看该作者
/**@}*//**

* @brief 向环形缓冲区写入数据

* @param [in] buf        : buf地址

* @param [in] len        : 字节长度

* @return  正确 : 返回写入的数据长度

失败 : -1*/int32_t PutData(uint8_t*buf, uint32_t len)

{

int32_t count=0;if(NULL ==buf)

{

printf("ERROR: gizPutData buf is empty \n");return-1;

}

count= rbWrite(&pRb, buf, len);if(count !=len)

{

printf("ERROR: Failed to rbWrite \n");return-1;

}

USART_ITConfig(USART1, USART_IT_TXE, ENABLE);returncount;

}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

255

帖子

0

粉丝