完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
串口通信基本原理
处理器与外部设备通信的两种方式 并行通信
UART: 通用异步收发器 USART: 通用同步异步收发器 大容量STM32F10x系列芯片,包含3个USART和2个UART UART异步通信方式引脚连接方法:
UART异步通信方式特点:
发射器控制(发射器时钟)和接收器控制(接收器时钟)受到同一个单元控制。 串口寄存器配置 常用的串口相关寄存器 USART_SR状态寄存器 USART_DR数据寄存器(只用到了位0-8) USART_BRR波特率寄存器 USART_CR1控制寄存器(使能) 波特率计算方法 串口操作相关库函数(省略入口参数): void USART_Init(); //串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能 void USART_Cmd();//使能串口 void USART_ITConfig();//使能相关中断 //DR寄存器 void USART_SendData();//发送数据到串口,DR uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据 //SR寄存器 FlagStatus USART_GetFlagStatus();//获取状态标志位 void USART_ClearFlag();//清除状态标志位 ITStatus USART_GetITStatus();//获取中断状态标志位 void USART_ClearITPendingBit();//清除中断状态标志位 USART_Init(); void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) typedef struct { uint32_t USART_BaudRate; //波特率 uint16_t USART_WordLength; //字长 uint16_t USART_StopBits; //停止位 uint16_t USART_Parity; //奇偶校验位 uint16_t USART_Mode; //发送接收使能 uint16_t USART_HardwareFlowControl; //硬件流控制 } USART_InitTypeDef; 串口配置的一般步骤 串口时钟使能,GPIO时钟使能: RCC_APB2PeriphClockCmd(); 串口复位:这一步不是必须的 USART_DeInit(); GPIO端口模式设置:要查表“STM32中文参考手册”8.1.11,模式设置为GPIO_Mode_AF_PP(复用为串口一设置为复用推挽) GPIO_Init(); 串口参数初始化: USART_Init(); 开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤) NVIC_Init();//优先级设置 USART_ITConfig();//确定开启哪个中断 使能串口: USART_Cmd(); 编写中断处理函数: USARTx_IRQHandler(); 串口数据收发: void USART_SendData();//发送数据到串口,DR uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据 串口传输状态获取: FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); 程序实践 main.c void My_USART_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //使能时钟 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA ,ENABLE); RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 ,ENABLE); //GPIOA9模式设置为GPIO_Mode_AF_PP GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); //GPIOA10模式设置为GPIO_Mode_AF_PP GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); //串口初始化 USART_InitStructure.USART_BaudRate=115200; USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//不使用硬件流 USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//接收发送都使能 USART_InitStructure.USART_Parity=USART_Parity_No;//不用奇偶校验,通信双方要么都有要么都没有 USART_InitStructure.USART_StopBits=USART_StopBits_1;//一个停止位,传输停止的标志 USART_InitStructure.USART_WordLength=USART_WordLength_8b;//没有奇偶校验取八 USART_Init(USART1,&USART_InitStructure); //使能串口 USART_Cmd(USART1,ENABLE); //使能哪个串口中断 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//确定开启哪个中断,并开启接收中断(即接收到数据执行中断服务函数) //设置响应中断优先级 NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//入口参数,在stm32f10x.h头文件447行 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//是否开启中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//设置抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//响应优先级 NVIC_Init(&NVIC_InitStructure); } void USART1_IRQHandler(void) //接收到数据执行这个中断 { u8 res; if(USART_GetITStatus(USART1,USART_IT_RXNE))//判断是否接收到数据 { res=USART_ReceiveData(USART1);//接受到的值赋给变量 USART_SendData(USART1,res);//发送接收到的数据 } } int main(void) { //中断设置 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //分组选择为2,两位响应两位抢占 My_USART_Init(); while(1);//使用中断接收,使用死循环 } 串口实验讲解 #define USART_REC_LEN 200 //定义最大接收字节数 200 u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 u16 USART_RX_STA; //接收状态标记 程序要求,发送的字符是以回车换行结束(0x0D,0x0A) eg:ABCDEFGHI…….(0x0D),(0x0A) bit15标记为1时候提取USART_RX_BUF中bit13~0个有效数据 串口终端服务函数: void USART1_IRQHandler(void) //串口1中断服务程序 { u8 Res; #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS. OSIntEnter(); #endif if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { Res =USART_ReceiveData(USART1); //读取接收到的数据 if((USART_RX_STA&0x8000)==0)//最高位如果是0,接收未完成,继续下面的接收 { if(USART_RX_STA&0x4000)//接收到了0x0d 即bit14是否为1 { if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 else USART_RX_STA|=0x8000; //接收完成了 ,最高位设为1 } else //还没收到0X0D { if(Res==0x0d)USART_RX_STA|=0x4000; else { USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;//只可以用bit13~0 USART_RX_STA++; if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收 } } } } #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS. OSIntExit(); #endif } main(); int main(void) { u16 t; u16 len; u16 times=0; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init(); //LED端口初始化 KEY_Init(); //初始化与按键连接的硬件接口 while(1) { if(USART_RX_STA&0x8000) //接收完成返回1 { len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度 printf("rn您发送的消息为:rnrn"); for(t=0;t USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束 } printf("rnrn");//插入换行 USART_RX_STA=0; }else { times++; if(times%5000==0) { printf("rn精英STM32开发板 串口实验rn"); printf("正点原子@ALIENTEKrnrn"); } if(times%200==0)printf("请输入数据,以回车键结束n"); if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行. delay_ms(10); } } } |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9057 浏览 16 评论
4086 浏览 18 评论
1175浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 12:06 , Processed in 1.151592 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号