完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
usart.c的文件介绍:
官方给出的usart库函数: 使UASRT串口可用printf函数发送 在usart.h文件里可更换使用printf函数的串口号 对printf的相关设定 #if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 _sys_exit(int x){ x = x; } //重定义fputc函数 int fputc(int ch, FILE *f){ while((USART_n->SR&0X40)==0);//循环发送,直到发送完毕 USART_n->DR = (u8) ch; return ch; } #endif USART1串口相关程序 USART使用与屏蔽选择 #if EN_USART1 //USART1使用与屏蔽选择 u8 USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. //接收状态 //bit15, 接收完成标志 //bit14, 接收到0x0d //bit13~0, 接收到的有效字节数目 u16 USART1_RX_STA=0; //接收状态标记 USART1专用的printf函数 当同时开启2个以上串口时,printf函数只能用于其中之一,其他串口要自创独立的printf函数 调用方法:USART1_printf(“123”); //向USART1发送字符123 void USART1_printf (char *fmt, ...){ char buffer[USART1_REC_LEN+1]; // 数据长度 u8 i = 0; va_list arg_ptr; va_start(arg_ptr, fmt); vsnprintf(buffer, USART1_REC_LEN+1, fmt, arg_ptr); while ((i < USART1_REC_LEN) && (i < strlen(buffer))){ USART_SendData(USART1, (u8) buffer[i++]); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); } va_end(arg_ptr); } 串口1初始化并启动 void USART1_Init(u32 bound){ //函数调用时可直接设置波特率 //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟 //USART1_TX PA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //USART1_RX PA.10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //USART 初始化设置(基本性能) USART_InitStructure.USART_BaudRate = bound;//一般设置为9600(波特率设置); USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位 USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 USART_Init(USART1, &USART_InitStructure); //初始化串口 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启ENABLE/关闭DISABLE中断 (串口中断) USART_Cmd(USART1, ENABLE); //使能串口 } 还有串口中断服务程序,在需要串口中断时再写 usart2与usart3的相关程序函数与usart1类似,不再赘述。 usart.h中的相关设置 #define USART_n USART1 //定义使用printf函数的串口,其他串口要使用USART_printf专用函数发送 #define USART1_REC_LEN 200 //定义USART1最大接收字节数 #define USART2_REC_LEN 200 //定义USART2最大接收字节数 #define USART3_REC_LEN 200 //定义USART3最大接收字节数 //不使用某个串口时要禁止此串口,以减少编译量 #define EN_USART1 1 //使能(1)/禁止(0)串口1 #define EN_USART2 0 //使能(1)/禁止(0)串口2 #define EN_USART3 0 //使能(1)/禁止(0)串口3 usart的应用 usart的发送程序 int main (void){//主程序 u8 a=7,b=8; //初始化程序 RCC_Configuration(); //时钟设置 USART1_Init(115200); //串口初始化(参数是波特率) //主循环 while(1){ /* 发送方法1 */ // USART_SendData(USART1 , 0x55); //发送单个数值 // USART_SendData(USART1 , 'U'); //使用单引号与上面等价 // while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); //检查发送中断标志位 /* 发送方法2 */ // printf("STM32F103 "); //纯字符串发送数据到串口 // printf("STM32 %d %d ",a,b); //纯字符串和变量发送数据到串口,a符号变量 /* 发送方法3 */ USART1_printf("STM32 %d",2); // USART2_printf("STM32 %d",2); // USART3_printf("STM32 %d",2);//使用usart2或者3时要先进行对应的初始化再使用 delay_ms(1000); //延时 } } usart的接收程序 方式一:查询方式 使用查询方式前,应关闭串口中断:在usart.c中设置 USART_ITConfig(USART1, USART_IT_RXNE,DISABLE);//关闭中断 int main (void){//主程序 u8 a; //初始化程序 RCC_Configuration(); //时钟设置 USART1_Init(115200); //串口初始化(参数是波特率) // USART1_IRQHandler(); //主循环 while(1){ // //查询方式接收 // if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET){ //查询串口待处理标志位 // a =USART_ReceiveData(USART1);//读取接收到的数据 // printf("%c",a); //把收到的数据发送回电脑 // } // // delay_ms(1000); //延时 } } 查询方式实时性不足,反应时间长。 方式二:中断方式 使用中断方式前,应开启串口中断:在usart.c中设置 USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);//开启中断1 当串口收到数据时,会跳转到串口中断程序。 中断函数写在usart.c中 void USART1_IRQHandler(void){ //串口1中断服务程序(固定的函数名不能修改) u8 a; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){ //接收中断(接收到的数据必须是0x0d 0x0a结尾) a =USART_ReceiveData(USART1);//读取接收到的数据 printf("%c",a); //把收到的数据发送回电脑 } } 串口控制应用 结合串口发送与接收,并配置usart.h应用,注意相关硬件的初始化 int main (void){//主程序 u8 a; //初始化程序 RCC_Configuration(); //时钟设置 LED_Init();//LED初始化 KEY_Init();//按键初始化 BUZZER_Init();//蜂鸣器初始化 USART1_Init(115200); //串口初始化(参数是波特率) //主循环 while(1){ //查询方式接收 if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET){ //查询串口待处理标志位 a =USART_ReceiveData(USART1);//读取接收到的数据 switch (a){ case '0': GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0)); //LED控制 printf("%c:LED1 OFF ",a); // break; case '1': GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); //LED控制 printf("%c:LED1 ON ",a); // break; case '2': BUZZER_BEEP1(); //蜂鸣一声 printf("%c:BUZZER ",a); //把收到的数据发送回电脑 break; default: break; } } //按键控制 if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平 delay_ms(20); //延时20ms去抖动 if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平 while(!GPIO_ReadInputDataBit(KEYPORT,KEY1)); //等待按键松开 printf("KEY1 "); // } 超级终端串口控制程序 主程序 int main (void){//主程序 RCC_Configuration(); LED_Init();//LED初始化 KEY_Init();//按键初始化 BUZZER_Init();//蜂鸣器初始化 USART1_Init(115200); //串口初始化,参数中写波特率 USART1_RX_STA=0xC000; //初始值设为有回车的状态,即显示一次欢迎词 while(1){ if(USART1_RX_STA&0xC000){ //如果标志位是0xC000表示收到数据串完成,可以处理。 if((USART1_RX_STA&0x3FFF)==0){ //单独的回车键再显示一次欢迎词 printf(" 33[1;47;33mrn"); //设置颜色(参考超级终端使用) printf(" 1y--开LED1灯 1n--关LED1灯 rn"); printf(" 2y--开LED2灯 2n--关LED2灯 rn"); printf(" 请输入控制指令,按回车键执行! 33[0mrn"); }else if((USART1_RX_STA&0x3FFF)==2 && USART1_RX_BUF[0]=='1' && USART1_RX_BUF[1]=='y'){ //判断数据是不是2个,第一个数据是不是“1”,第二个是不是“y” GPIO_SetBits(LEDPORT,LED1); //LED灯都为高电平(1) printf("1y -- LED1灯已经点亮!rn"); }else if((USART1_RX_STA&0x3FFF)==2 && USART1_RX_BUF[0]=='1' && USART1_RX_BUF[1]=='n'){ GPIO_ResetBits(LEDPORT,LED1); LED灯都为低电平(0) printf("1n -- LED1灯已经熄灭!rn"); }else if((USART1_RX_STA&0x3FFF)==2 && USART1_RX_BUF[0]=='2' && USART1_RX_BUF[1]=='y'){ GPIO_SetBits(LEDPORT,LED2); //LED灯都为高电平(1) printf("2y -- LED2灯已经点亮!rn"); }else if((USART1_RX_STA&0x3FFF)==2 && USART1_RX_BUF[0]=='2' && USART1_RX_BUF[1]=='n'){ GPIO_ResetBits(LEDPORT,LED2); LED灯都为低电平(0) printf("2n -- LED2灯已经熄灭!rn"); }else{ //如果以上都不是,即是错误的指令。 printf("指令错误!rn"); } USART1_RX_STA=0; //将串口数据标志位清0 } } } 超级终端的串口中断:串口1中断服务程序(固定的函数名不能修改) 中断函数写在usart.c中 void USART1_IRQHandler(void){ u8 Res; //以下是字符串接收到USART1_RX_BUF[]的程序,(USART1_RX_STA&0x3FFF)是数据的长度(不包括回车) //当(USART1_RX_STA&0xC000)为真时表示数据接收完成,即超级终端里按下回车键。 //在主函数里写判断if(USART1_RX_STA&0xC000),然后读USART1_RX_BUF[]数组,读到0x0d 0x0a即是结束。 //注意在主函数处理完串口数据后,要将USART1_RX_STA清0 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){ //接收中断(接收到的数据必须是0x0d 0x0a结尾) Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据 printf("%c",Res); //把收到的数据以 a符号变量 发送回电脑 if((USART1_RX_STA&0x8000)==0){//接收未完成 if(USART1_RX_STA&0x4000){//接收到了0x0d if(Res!=0x0a)USART1_RX_STA=0;//接收错误,重新开始 else USART1_RX_STA|=0x8000; //接收完成了 }else{ //还没收到0X0D if(Res==0x0d)USART1_RX_STA|=0x4000; else{ USART1_RX_BUF[USART1_RX_STA&0X3FFF]=Res ; //将收到的数据放入数组 USART1_RX_STA++; //数据长度计数加1 if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//接收数据错误,重新开始接收 } } } } } #endif |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1618 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1545 浏览 1 评论
979 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1597 浏览 2 评论
1864浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
645浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
516浏览 3评论
532浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
505浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 19:09 , Processed in 0.619230 second(s), Total 72, Slave 56 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号