完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
2. 准备工作(此次实验根据上一次的PWM的程序进行改造得来) 串口的使用对于单片机来讲是公用的,也就是说我们这次所书写的程序可以用于以后的程序来使用, 所以可以将该实验的程序代码放在一个公共文件夹我命名为Public(我看的视频教程中的文件夹就是这样,哈哈)中, 和位带程序和Systick程序一起。 操作过程复述: 串口配置函数: (1) 建立Usart.c和Usart.h文件,存放于Public文件,添加到工程里。 (2) 查找rcc.h文件,发现USART1串口挂接在APB2总线上,于是先使能APB2总线。 (3) 既然USART1的读写口都挂接在GPIOA上,就需要将GPIOA使能, 为了增强程序的可移植性,将GPIOA宏定义为USART1_GPIO,相应的管脚也宏定义 使能USART_GPIO 下面配置需要使用的GPIOA的管脚。 基本步骤,定义一个结构体后配置好相应的参数。 两个管脚的模式为什么要这样设定我还不是很懂。 接下来是串口的配置了。 (4) 类似于GPIO的初始化操作一样。 结构体有6个参数 USART_BaudRate 比特率 USART_WordLength 数据字节长度 USART_StopBits 停止位长度 USART_Parity 奇偶校验选项 USART_HardwareFlowControl 硬件流控制选项 USART_Mode 串口模式选项 之后是使能串口 下一步是清除串口中断的标志位,可以不加,加上过后可以提高程序的稳定性。 USART_FLAG_TC表明串口中断完成。 下面是使能串口中断(让串口可以接收中断) USART_IT_RXNE:接收中断 (5)最后设置NVIC相关操作。 所有关于串口中断的启动程序就写完了,下面就是关于中断服务函数的书写。 中断服务函数: 实现的功能是PC向单片机发送数据,然后单片机将数据回显给PC机。 首先,需要有一个可以存储我们PC机发送数据的一个临时变量,首先让变量等于我们的PC机发送的数据,然后再将该变量回发给我们的PC机即可, while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET); 这句话的意思是,当我们的串口发送完成的时候,函数返回值是1,而SET在库函数中的值也是1,此时就会使得while内的条件为0,即为假,while循环便会退出,完成一次中断的服务。 而没有完成发送的时候,函数的返回值是0,while内的条件一直是1,循环就不会退出,使得我们可以继续发送数据,直到我们的数据发送完成。 下面是代码部分 Usart.h #ifndef _USART_H #define _USART_H #include "system.h" void USART1_Init(u32 bound); #define USART1_TX_PIN GPIO_Pin_9 #define USART1_RX_PIN GPIO_Pin_10 #define USART1_GPIO GPIOA #endif Usart.c #include "Usart.h" //时间:2020-1-14 //制作者:SaBo //适用:STM32F103ZET6 (普中科技 PZ6800L) //串口的初始化函数,GPIO、NVIC、USART初始化的程序书写地方 void USART1_Init(u32 bound) { NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量 USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //GPIOA_PIN_9是输出数据的管脚,设置为复用输出模式 //TX GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; //选择你要设置的IO口 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //设置推挽输出模式 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率 GPIO_Init(USART1_GPIO,&GPIO_InitStructure); /* 初始化GPIO */ //GPIOA_PIN_10是数据的接收管脚,设置为浮空输入模式 //RX GPIO_InitStructure.GPIO_Pin=USART1_RX_PIN; //选择你要设置的IO口 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //设置推挽输出模式 GPIO_Init(USART1_GPIO,&GPIO_InitStructure); /* 初始化GPIO */ //串口配置 USART_InitStructure.USART_BaudRate=bound; //波特率由参数设置 USART_InitStructure.USART_WordLength=USART_WordLength_8b; //八个字节长度 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_Cmd(USART1,ENABLE); //清除标志位 USART_ClearFlag(USART1,USART_FLAG_TC);//发送完成的标识清除,用于增加程序的健壮性 //使能中断 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //设置优先级 NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; NVIC_InitStructure.NVIC_IRQChannelSubPriority=3; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); } //中断服务函数 void USART1_IRQHandler() { u8 r; //不等于0,就是接收到中断,执行服务函数 if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) { //按字节接收 //接收数据函数 r=USART_ReceiveData(USART1); USART_SendData(USART1,r); //发送数据函数 //发送完成的标识 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//发送完成的话,这个标识会被置为1,当返回值是1的时候,就会退出这个while循环表明我们的数据发送完成。 } } main.c #include "system.h" #include "SysTick.h" #include "led.h" #include "pwm.h" #include "Usart.h" //时间:2020-1-14 //制作者:SaBo //适用:STM32F103ZET6 (普中科技 PZ6800L) /********************************************* 程序写好后,下载到开发板上,打开我们的串口调试助手, 设置波特率为9600,数据位8位,停止位1位 发送什么就会在串口调试助手上回显出来。 led1的闪烁表明我们的程序是否正常在进行。(检测作用) *********************************************/ //--------------------------------------- //名称:主函数 //适用:STM32F103ZET6 (普中科技 PZ6800L) //日期:2020-1-14 //--------------------------------------- int main() { u8 i; SysTick_Init(72); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); LED_Init(); USART1_Init(9600); while(1) { i++; if(i%20 == 0) led1=!led1; delay_ms(10); } } |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2956 浏览 16 评论
3456 浏览 1 评论
8988 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 12:13 , Processed in 1.088668 second(s), Total 81, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号