利用stm32串口中断进行数码管显示

为了使得本次实验的效果更加明显,我将利用串口中断,在中断服务程序中读取串口输入的数值,然后在数码管上显示出该数值。

一、数码管配置

         在进行本次的实验之前,由于需要使用数码管进行实验结果的显示,我们首先需要数码管的真值表,我这边使用的是普通的共阳极数码管,所以真值表如下:

        

0

1

2

3

4

5

6

7

0xc0

0xf9

0xA4

0xB0

0x99

0x92

0x82

0xF8

8

9

a

b

c

d

e

f

0x80

0x90

0x88

0x83

0xC6

0xA1

0x86

0x8E






   以上准备工作完成以后,可以正式进入本次实验了。很明显,我们用到了数码管和串口,因此我们至少需要数码管配置函数以及串口配置函数这两个配置函数。对于数码管的配置函数,由于我使用的普中PZ6806L型的开发板,通过查询原理图发现数码管的各个段对应于LED1~LED8,然后接到GPIOC的0~7管脚上,因此配置好GPIOC就可以了,这个简单,直接给出代码如下: void segmentDisplayInit() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); } 二、串口配置 下面是本次实验的重点,也就是RS232串口中断配置函数usartInit(),在《STM32中文参考手册》中对USART的描述如下: 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率 选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器 通信。 串口通信一般有三种形式,即查询方式、中断方式和DMA方式。查询方式(也有人称为轮询法)效率不高,在需要查询时CPU的占用很高,在程序上的体现就是用循环不断 查询标志位状态,在查询时CPU不做其他事,因此效率是比较低的。中断方式的话,只有在发送中断、接收中断、传输完成中断等的中断时会进入串口中断服务程序,这样CPU就 不用等在那儿,该干嘛干嘛,大大提高了效率,因此本次实验采用中断方式。而DMA方式的话,由于在微机原理课程中没有进行相关知识的学习,故了解不多,不敢进行评论。 在串口中断初始化配置中,首先应打开串口时钟和PA口的时钟(AFIO的时钟可以不用打开),打开PA口时钟的原因是,在本实验中,我使用的板子在原理图上显示,RS232串口的 RX和TX分别与PA10和PA9相连。接着就该根据TX、RX配置PA9和PA10这两个GPIO了,这里要注意的是这里模式最好要设置成浮空输入和复用推挽输出,至少按下表设置: 接下来就要调用USART_Init()程序对串口进行参数配置,该函数的入口参数是一个结构体指针USART_InitTypeDef*,查询stm32f10x_usart.h可得,该结构体定义如下: typedef struct {   uint32_t USART_BaudRate;  //波特率,一般9600即可   uint16_t USART_WordLength;//字长八位或九位   uint16_t USART_StopBits;   //停止位选择   uint16_t USART_Parity;  //奇偶校验   uint16_t USART_Mode;  //模式,发送还是接收   uint16_t USART_HardwareFlowControl;//硬件控制流,一般设置为NONE }USART_InitTypeDef; 接着打开串口,使用USART_Cmd(USART1,ENABLE);即可。 然后打开串口中断,这里我打开接收中断,函数如下: USART_ITConfig(USART1,USART_IT_RXNE, ENABLE); 最后配置串口中断的优先级,这个配置在上一篇定时器中断的配置中已经介绍过了,这里不再赘述。 综合以上几点usart总的配置函数给出如下: void usartInit() { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //时钟配置 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE); //TX和RX对应GPIO的初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); //串口基本参数初始化 USART_InitStructure.USART_BaudRate = 9600; 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_Tx | USART_Mode_Rx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //串口中断优先级配置 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } 三、串口中断函数 在此函数中只要检测输入的数据,然后将对应的数码管真值表的值写到GPIOC上即可。这里直接给出程序: void USART1_IRQHandler(void) { static u8 k; int seg[] = {0xc0 , 0xf9 , 0xA4 , 0xB0 , 0x99 , 0x92 , 0x82 , 0xF8 , 0x80  , 0x90 , 0x88 , 0x83 , 0xC6 , 0xA1 , 0x86 , 0x8E}; USART_ClearFlag(USART1 , USART_FLAG_TC); if(USART_GetITStatus(USART1 , USART_IT_RXNE) != Bit_RESET) { k = USART_ReceiveData(USART1); GPIO_Write(GPIOC , seg[k]); } } 主函数很简单,这里就不给出了。





你可能感兴趣的:(stm32)