写完这篇文章想着以后尽量(应该说一定)使用现在正在使用的LPC系列的单片机写程序,其实内心感觉还是LPC做的相当完善,,,,,配置上没有32那么的繁琐....
关于串口发送数据,自己以前呢是这样
voidUsart_Out_Char(unsignedchar*c,uint32_t cnt)
{while(cnt--)
{
USART_SendData(USART1,*c++);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) ==RESET );
}
}
下面的调用方式
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);
}
}
当发送数据的时候,会一直在调用此函数的地方等着,,,,,,直至发送完所有的数据,要知道用串口中断发送数据要比这样发送快的多.......瞎耽误时间
假设现在我用中断发送
假设没有缓冲区
voidUsartOutChar(unsignedchar*Buff,uint32_t cnt)
{
dat=Buff;//把发送地址给dat
BuffCnt=cnt;//记录发送的个数
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//打开发送中断
}
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);
}
}
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);}
}
加一个缓冲区---假设是下面这样子,中断发送的数据从这个缓冲区里面取
然后呢,接着又填入了
接着
假设我又想添加数据,可是呢后面空的那一块数据空间不够了......要是能把数组的尾和头联系起来就好啦......
假设加满了,,,如果能自动的加到前面就好啦.....
今天先这样...太晚啦..现在最大的愿望什么时候能安心睡个早觉..再这样下去真担心会挂了......有空再详加..
下面是实现程序--实现程序是自己想学Esp8266连接机智云的时候无意中看到的,,,,,记得 天鲁哥 曾经说过环形队列实现的很巧妙,,,改天有空再研究下当初天鲁哥给的程序
往里面加数据尾指针向右增加...加到头回到首地址
从里面读数据头指针向右增加...加到头回到首地址
注意
还是在唠叨唠叨
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;//长度为空}
int32_t rbCapacity(rb_t*rb)//获取链表的长度{if(NULL ==rb)
{
printf("ERROR: input rb is NULL\n");return-1;
}returnrb->rbCapacity;
}
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);//头大于尾}
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;
}
}
}
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;
}
}/**@}*//**
* @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;
}
#ifndef LOOPLIST_H_#defineLOOPLIST_H_#ifndef LOOPLIST_C_//如果没有定义 AnnularArray_C_#defineLOOPLIST_C_ extern#else#defineLOOPLIST_C_#endif#include#definesize_t uint16_t#defineRB_MAX_LEN 1024//缓冲区最大长度#definemin(a, b) (a)<(b)?(a):(b)///< 获取最小值/** 环形缓冲区数据结构*/typedefstruct{
size_t rbCapacity;//空间大小uint8_t *rbHead;//头uint8_t *rbTail;//尾uint8_t *rbBuff;//数组的首地址}rb_t;
LOOPLIST_C_ rb_t pRb;///< 环形缓冲区结构体变量LOOPLIST_C_ uint8_t rbBuf[RB_MAX_LEN];///< 环形缓冲区数据缓存区LOOPLIST_C_voidrbCreate(rb_t *rb,u8 *Buff,uint32_t BuffLen);//创建或者说初始化环形缓冲区LOOPLIST_C_voidrbDelete(rb_t*rb);
LOOPLIST_C_ int32_t rbCapacity(rb_t*rb);//得到环形大小LOOPLIST_C_ int32_t rbCanRead(rb_t *rb);//能读出数据的个数LOOPLIST_C_ int32_t rbCanWrite(rb_t *rb);//还剩余的空间LOOPLIST_C_ int32_t rbRead(rb_t *rb,void*data, size_t count);//读取数据LOOPLIST_C_ int32_t rbWrite(rb_t *rb,constvoid*data, size_t count);
LOOPLIST_C_ int32_t PutData(uint8_t*buf, uint32_t len);#endif
使用就很方便了--直接往里面填数据就好啦
#include"include.h"uint8_t aaa[50]={1,1,1,1,1,1,1,1,1,1};
uint8_t bbb[50]={3,3,3,3,3,3,3,3,3,3};intmain(void)
{
NVIC_Configuration();
Led_Gpio_Init();
Timer2_Config();
uart_init(115200);//串口初始化为115200rbCreate(&pRb,SendBuff,USART_REC_LEN);//创建环形队列while(1)
{
PutData(aaa,10);//发送数据PutData(bbb,10);//发送数据delay_ms(10);
}
}
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(rbCanRead(&pRb)>0)//如果里面的数据个数大于0{
rbRead(&pRb, &SendDat,1);//读取一个数据USART_SendData(USART1, SendDat);//发送}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);
}
}
其实再完美点就是加上DMA....后期我尽量用LPC的单片机做....不对是一定要用LPC的单片机做成dma的---
程序链接:http://pan.baidu.com/s/1pLlXDfP密码:6kci