您的位置 首页 传感器

STM32串口寄存器操作

//USART.C/******************************************************************************************

//USART.C

/*********************************************************************************************************//* USART 收发  *//* 陈鹏 20110611*/#include "SYSTEM.H"#include "GPIO_INIT.H"#include "USART.H"//界说串口通道号最大值#define UART_ChMax 1//UART外设结构指针static const  USART_TypeDef * USARTxN[5] = {USART1,USART2,USART3,UART4,UART5};//相关UART状况结构typedef struct{  FlagStatus  NewDataFlag;//接纳到新数据  FlagStatus  BuffFull; //接纳Buff满  FlagStatus  IntRx; //是否敞开中止接纳  u8 *RxBuff;//接纳Buff指针  u16 RxBuffSize;//接纳缓冲区巨细,一帧数据巨细  u16 UartRxCnt;//接纳数据计数器} UartRx_TypeDef;//UART1 接纳状况结构static UartRx_TypeDef UartRx[UART_ChMax + 1];////////////////////////////////////////////////////////////////////参加以下代码,支撑printf函数,而不需求挑选use MicroLIB  #if 1#pragma import(__use_no_semihosting)             //规范库需求的支撑函数                 struct __FILE {   int handle;   /* Whatever you require here. If the only file you are using is */   /* standard output using printf() for debugging, no file handling */   /* is required. */ }; /* FILE is typedef’ d in stdio.h. */ FILE __stdout;       //界说_sys_exit()以防止运用半主机形式    _sys_exit(int x) {   x = x; } //重界说fputc函数 int fputc(int ch, FILE *f){        UARTx_SendByte(0,(u8)ch);        return ch;}#endif //end///////////////////////////////////////////////////////////////////************************************************************************************************************************** 函数 :  u8 UARTx_Init(u8 ch,u8 SYS_CLK,u32 Speed,u8 RX_Int)* 功用 :  串口初始化* 参数 :  ch:通道挑选,0->usart1;SYS_CLK当时体系时钟,Speed:串口速度,RX_Int:是否时能中止承受* 回来 :  0:成功,1:失利* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20120403* 最终修正时刻 : 20120403* 阐明 : USART1~UART5,对应通道0~4*************************************************************************************************************************/u8 UARTx_Init(u8 ch,u8 SYS_CLK,u32 Speed,u8 RX_Int){  USART_TypeDef *UARTx = (USART_TypeDef *)USARTxN[ch];   //获取对应通道硬件基址指针  u32 clock;  u8 irq_n;  float fclk;  if(ch > UART_ChMax)  return 1;  //端口号超出范围  //初始化UART IO  DeviceClockEnable(DEV_AFIO,ENABLE);//复用功用AFIO时钟使能  switch (ch)  {    case 0:  //通道0,USART1 ,TX:PA9;RX:PA10    {      DeviceClockEnable(DEV_GPIOA,ENABLE);//GPIO A 时钟使能      DeviceClockEnable(DEV_USART1,ENABLE);//USART 1 时钟使能      GPIOx_Init(GPIOA,BIT9,AF_PP, SPEED_10M);         //PA09,TXD只能设置成复用推挽输出      GPIOx_Init(GPIOA,BIT10,IN_FLOATING,IN_IN);  //浮空输入      DeviceReset(DEV_USART1);//复位串口1      irq_n =  IRQ_USART1;//串口1中止号    }break;    case 1:  //通道1,USART2 ,TX:PA2;RX:PA3    {       DeviceClockEnable(DEV_GPIOA,ENABLE);//GPIO A 时钟使能      DeviceClockEnable(DEV_USART2,ENABLE);//USART 2 时钟使能      GPIOx_Init(GPIOA,BIT2,AF_PP, SPEED_10M);         //PA2,TXD只能设置成复用推挽输出      GPIOx_Init(GPIOA,BIT3,IN_FLOATING,IN_IN);  //浮空输入      DeviceReset(DEV_USART2);//复位串口2      irq_n =  IRQ_USART2;//串口2中止号    }break;    case 2:  //通道2,USART3 ,TX:PD8;RX:PD9    {      DeviceClockEnable(DEV_GPIOD,ENABLE);//GPIO D 时钟使能      DeviceClockEnable(DEV_USART3,ENABLE);//USART 3 时钟使能      GPIOx_Init(GPIOD,BIT8,AF_PP, SPEED_10M);         //PD8,TXD只能设置成复用推挽输出      GPIOx_Init(GPIOD,BIT9,IN_FLOATING,IN_IN);  //浮空输入      DeviceReset(DEV_USART3);//复位串口3      irq_n =  IRQ_USART3;//串口3中止号    }break;    case 3:  //通道3,UART4 ,TX:PC10;RX:PC11    {      DeviceClockEnable(DEV_GPIOC,ENABLE);//GPIO C 时钟使能      DeviceClockEnable(DEV_UART4,ENABLE);//UART 4 时钟使能      GPIOx_Init(GPIOC,BIT10,AF_PP, SPEED_10M);   //PC10,TXD只能设置成复用推挽输出      GPIOx_Init(GPIOD,BIT11,IN_FLOATING,IN_IN);  //浮空输入      DeviceReset(DEV_UART4);//复位串口3      irq_n =  IRQ_UART4;//串口3中止号    }break;    case 4:  //通道4,UART5 ,TX:PC12;RX:PD2    {      DeviceClockEnable(DEV_GPIOC,ENABLE);//GPIO C 时钟使能      DeviceClockEnable(DEV_GPIOD,ENABLE);//GPIO D 时钟使能      DeviceClockEnable(DEV_UART5,ENABLE);//UART 5 时钟使能      GPIOx_Init(GPIOC,BIT12,AF_PP, SPEED_10M);   //PC12,TXD只能设置成复用推挽输出      GPIOx_Init(GPIOD,BIT2,IN_FLOATING,IN_IN);  //浮空输入      DeviceReset(DEV_UART5);//复位串口3      irq_n =  IRQ_UART5;//串口3中止号    }break;    default :       return 1;//端口号超出范围,回来过错  }  //设置波特率分频系数  clock = SYS_CLK * 1;//USART1时钟  if(ch > 0)  clock /= 2;  //USART2,3,4,5时钟  fclk = (float)clock / 16.0 / Speed;//核算波特率分频系数  clock = (u16)fclk;//得到波特率分频系数整数部分  UARTx->BRR =  clock << 4;//设置波特率整数部分  fclk -= clock;//得到波特率分频系数小数部分  fclk *= 16;  UARTx->BRR = 0xf & (u16)fclk;//设置波特率小数部分  //装备UART  UARTx->CR1 = 0x2;//使能USART,1个开端位,8位数据  UARTx->CR1 = 0x8;//置TE = 1;发送使能;发送第一个闲暇位  UARTx->CR1 = 0x04;//RE = 1;接纳使能  SetUartRxBuff(ch,0,NULL);//设置串口接纳缓冲区  UARTx_ClearRxInt(ch);  //铲除串口接纳中止标志  if(RX_Int)  {    UARTx->CR1 = 0x20;//RXNEIE = 1,开RXNE中止,即敞开接纳中止    NVIC_IntEnable(irq_n,1);//敞开USART1大局中止    UartRx[ch].IntRx = SET;//中止接纳标志有用  }   else  {    NVIC_IntEnable(irq_n,0);     //封闭USART大局中止    UartRx[ch].IntRx = RESET;//中止接纳标志无效  }  UARTx_SendByte(0,S);//发送一字节数据}/************************************************************************************************************************** 函数 :  u8 UARTx_Config(u8 ch,UART_Config_TypeDef * cfg)* 功用 :  串口装备* 参数 :  ch:通道挑选,0->usart1;cfg:串口装备结构指针* 回来 :  0:成功,非0:失利* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20120408* 最终修正时刻 : 20120408* 阐明 : USART1~UART5,对应通道0~4 ,回来1:校验设置过错,2:中止位设置过错,3:通道超出范围*************************************************************************************************************************/u8 UARTx_Config(u8 ch,UART_Config_TypeDef * cfg){USART_TypeDef *UARTx = (USART_TypeDef *)USARTxN[ch];   //获取对应通道硬件基址指针if(ch > UART_ChMax)//判别端口是否超出范围return 3;UARTx_PowerDown(ch);//进入掉电形式,进行装备switch (cfg->OddEvenVerify)//设置校验位{case UART_VERIFY_NULL://无校验{UARTx->CR1 &= ~BIT12;//一个开始位,8个数据位UARTx->CR1 &= ~BIT10;//制止校验操控}break;case UART_ODD://奇校验{UARTx->CR1 = BIT12;//一个开始位,9个数据位UARTx->CR1 = BIT10;//使能校验操控UARTx->CR1 = BIT9;//奇校验}break;case UART_EVEN://偶校验{UARTx->CR1 = BIT12;//一个开始位,9个数据位UARTx->CR1 = BIT10;//使能校验操控UARTx->CR1 &= ~BIT9;//偶校验}break;default : {UARTx_PowerOn(ch);//串口从头上电return 1;  //设置过错,回来校验设置过错1}}if(cfg->StopBitWidth == UART_STOP_1BIT) //设置中止位{UARTx->CR2 &= ~(0x3 << 12);//铲除设置,默许一个中止位}else if(cfg->StopBitWidth == UART_STOP_2BIT){UARTx->CR2 &= ~(0x3 << 12);UARTx->CR2 = (0x2 << 12);//2个中止位} else{UARTx_PowerOn(ch);//串口从头上电return 2;  //中止位设置过错,回来过错2}UARTx_PowerOn(ch);//串口从头上电return 0;  //设置完结,回来0}/************************************************************************************************************************** 函数 :  void UARTx_SendByte(u8 ch,u8 data)* 功用 :  UART单字节发送* 参数 :  ch:通道号,dataL:要发送的数据* 回来 :  无* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20120403* 最终修正时刻 : 20120403* 阐明 : 通道号为0 - 4;*************************************************************************************************************************/void UARTx_SendByte(u8 ch,u8 data){USART_TypeDef *UARTx = (USART_TypeDef *)USARTxN[ch];   //获取对应通道硬件基址指针if(ch > UART_ChMax)//判别端口是否超出范围return;while(!(UARTx->SR & 0x80));//等候发送寄存器为空,(不然接连发送时数据易丢掉 )UARTx->DR = data;//发送数据while(!(UARTx->SR & 0x40));//等候TC = 1;也便是发送完结UARTx->SR &= ~(1 << 6);//铲除发送完结标志}/************************************************************************************************************************** 函数 :  void UARTx_TX(u8 ch,u8 *tx_buff,u16 byte_number)* 功用 :  UART数据发送函数* 参数 :  ch:通道号,tx_buff:发送缓冲区,byte_number:需求发送的字节* 回来 :  无* 依靠 :  void UART_SendByte(u8 ch,u8 data)* 作者 :  陈鹏* 时刻 :  20120403* 最终修正时刻 : 20120403* 阐明 : 非DMA方法,非FIFO方法发送*************************************************************************************************************************/void UARTx_TX(u8 ch,u8 *tx_buff,u16 byte_number){u8 i;if(ch > UART_ChMax)//判别端口是否超出范围return;for(i = 0;i < byte_number;i++)//循环发送,直至发送结束{UARTx_SendByte(ch,tx_buff[i]);}}/************************************************************************************************************************** 函数 :  void UARTx_PowerDown(u8 ch)* 功用 :  UART掉电* 参数 :  ch:通道挑选* 回来 :  无* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20120403* 最终修正时刻 : 20120403* 阐明 : 进入低功耗形式;通道号为0 - 4;*************************************************************************************************************************/void UARTx_PowerDown(u8 ch){if(ch > UART_ChMax)//判别端口是否超出范围return;((USART_TypeDef *)USARTxN[ch])->BRR = (1 << 13);//UE位写一,敞开低功耗}/************************************************************************************************************************** 函数 :  void UARTx_PowerOn(u8 ch)* 功用 :  UART上电* 参数 :  ch:通道挑选* 回来 :  无* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20120403* 最终修正时刻 : 20120403* 阐明 : 退出低功耗形式;通道号为0 - 4;*************************************************************************************************************************/void UARTx_PowerOn(u8 ch){if(ch > UART_ChMax)//判别端口是否超出范围return;((USART_TypeDef *)USARTxN[ch])->BRR &= ~(1 << 13);//UE位清零,退出低功耗形式}/************************************************************************************************************************** 函数 :  u8 GetUartNewFlag(u8 ch)* 功用 :  获取串口新数据标志* 参数 :  ch:通道挑选* 回来 :  1:有新数据,0:无新数据* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20120403* 最终修正时刻 : 20120403* 阐明 : 用于判别是否有新的数据,会铲除去新数据标志的*************************************************************************************************************************/u8 GetUartNewFlag(u8 ch){if(ch > UART_ChMax)//判别端口是否超出范围return 0;if(UartRx[ch].IntRx == SET)//敞开了中止接纳{if(UartRx[ch].NewDataFlag == SET) //有新数据{UartRx[ch].NewDataFlag = RESET;//铲除标志return 1;  //回来有新数据}elsereturn 0;  //无新数据}else //没敞开中止接纳{if(((USART_TypeDef *)USARTxN[ch])->SR & BIT5)//RXNE=1,接纳到新数据{((USART_TypeDef *)USARTxN[ch])->SR &= ~BIT5;//铲除标志return 1;}else return 0;}}/************************************************************************************************************************** 函数 :  u8 GetUartRxBuffFullFlag(u8 ch)* 功用 :  获取串口接纳缓冲区满标志* 参数 :  ch:通道挑选* 回来 :  1:有新数据,0:无新数据* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20120403* 最终修正时刻 : 20120403* 阐明 : 用于判别接纳缓冲区是否满,会铲除标志*************************************************************************************************************************/u8 GetUartRxBuffFullFlag(u8 ch){if(ch > UART_ChMax)//判别端口是否超出范围return 0;if(UartRx[0].BuffFull == SET)//缓冲区已满{UartRx[0].BuffFull = RESET;//铲除满标志return 1;}return 0;}/************************************************************************************************************************** 函数 :  void UART_ClearRxInt(u8 ch)* 功用 :  铲除串口接纳中止标志* 参数 :  ch:通道挑选* 回来 :  物* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20120403* 最终修正时刻 : 20120403* 阐明 : 用于铲除接纳标志*************************************************************************************************************************/void UARTx_ClearRxInt(u8 ch){if(ch > UART_ChMax)//判别端口是否超出范围return;((USART_TypeDef *)USARTxN[ch])->SR &= ~BIT5;//铲除标志}/************************************************************************************************************************** 函数 :  u8 GetUartNewData(u8 ch)* 功用 :  获取串口新数据* 参数 :  ch:通道挑选* 回来 :  收到的数据* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20120403* 最终修正时刻 : 20120403* 阐明 : 用于接纳一个字节数据*************************************************************************************************************************/u8 GetUartNewData(u8 ch){if(ch > UART_ChMax)//判别端口是否超出范围return 0;return (((USART_TypeDef *)USARTxN[ch])->DR);//回来数据}/************************************************************************************************************************** 函数 :  void SetUartRxBuff(u8 ch,u16 RxBuffSize,u8 *RxBuff)* 功用 :  设置串口接纳缓冲区* 参数 :  ch:通道挑选,RxBuffSize:缓冲区巨细,RxBuff:缓冲区指针* 回来 :  无* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20120403* 最终修正时刻 : 20120403* 阐明 : 一定要设置,不然敞开中止接纳时可能会反常*************************************************************************************************************************/void SetUartRxBuff(u8 ch,u16 RxBuffSize,u8 *RxBuff){if(ch > UART_ChMax)//判别端口是否超出范围return;UartRx[ch].RxBuffSize = RxBuffSize; //设置缓冲区巨细UartRx[ch].RxBuff = RxBuff;//设置缓冲区指针UartRx[0].UartRxCnt = 0;//计数器清零}/************************************************************************************************************************** 函数 :  void USART1_IRQHandler (void)* 功用 :  UART1中止接纳函数* 参数 :  无* 回来 :  无* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20110611* 最终修正时刻 : 20120403* 阐明 : 无*************************************************************************************************************************/void USART1_IRQHandler (void){if((USART1->SR & BIT2)  (USART1->SR & BIT1))//假如NE = 1发送噪声过错  //假如FE = 1,发送帧过错{if(USART1->SR);if(USART1->DR);//复位NE操作序列}else if(UartRx[0].RxBuffSize > 0)//接纳缓冲区大于0{(UartRx[0].RxBuff)[(UartRx[0].UartRxCnt) ++] = USART1->DR;//将数据存放到缓冲区if(UartRx[0].UartRxCnt == UartRx[0].RxBuffSize)//缓冲区已满{UartRx[0].UartRxCnt = 0;//接纳计数器清零UartRx[0].BuffFull = SET;//缓冲区已满标志} }UartRx[0].NewDataFlag = SET;//收到新数据标志UARTx_ClearRxInt(0);  //铲除串口接纳中止标志}#if UART_ChMax > 0/************************************************************************************************************************** 函数 :  void USART2_IRQHandler (void)* 功用 :  UART2中止接纳函数* 参数 :  无* 回来 :  无* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20110611* 最终修正时刻 : 20120403* 阐明 : 无*************************************************************************************************************************/void USART2_IRQHandler (void){if((USART2->SR & BIT2)  (USART2->SR & BIT1))//假如NE = 1发送噪声过错  //假如FE = 1,发送帧过错{if(USART2->SR);if(USART2->DR);//复位NE操作序列}else if(UartRx[1].RxBuffSize > 0)//接纳缓冲区大于0{(UartRx[1].RxBuff)[(UartRx[1].UartRxCnt) ++] = USART1->DR;//将数据存放到缓冲区if(UartRx[1].UartRxCnt == UartRx[1].RxBuffSize)//缓冲区已满{UartRx[1].UartRxCnt = 0;//接纳计数器清零UartRx[1].BuffFull = SET;//缓冲区已满标志} }UartRx[1].NewDataFlag = SET;//收到新数据标志UARTx_ClearRxInt(1);  //铲除串口接纳中止标志}#endif#if UART_ChMax > 1/************************************************************************************************************************** 函数 :  void USART3_IRQHandler (void)* 功用 :  UART3中止接纳函数* 参数 :  无* 回来 :  无* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20110611* 最终修正时刻 : 20120403* 阐明 : 无*************************************************************************************************************************/void USART3_IRQHandler (void){if((USART3->SR & BIT2)  (USART3->SR & BIT1))//假如NE = 1发送噪声过错  //假如FE = 1,发送帧过错{if(USART3->SR);if(USART3->DR);//复位NE操作序列}else if(UartRx[2].RxBuffSize > 0)//接纳缓冲区大于0{(UartRx[2].RxBuff)[(UartRx[2].UartRxCnt) ++] = USART1->DR;//将数据存放到缓冲区if(UartRx[2].UartRxCnt == UartRx[2].RxBuffSize)//缓冲区已满{UartRx[2].UartRxCnt = 0;//接纳计数器清零UartRx[2].BuffFull = SET;//缓冲区已满标志} }UartRx[2].NewDataFlag = SET;//收到新数据标志UART_ClearRxInt(2);  //铲除串口接纳中止标志}#endif#if UART_ChMax > 2/************************************************************************************************************************** 函数 :  void UART4_IRQHandler (void)* 功用 :  UART4中止接纳函数* 参数 :  无* 回来 :  无* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20110611* 最终修正时刻 : 20120403* 阐明 : 无*************************************************************************************************************************/void UART4_IRQHandler (void){if((UART4->SR & BIT2)  (UART4->SR & BIT1))//假如NE = 1发送噪声过错  //假如FE = 1,发送帧过错{if(UART4->SR);if(UART4->DR);//复位NE操作序列}else if(UartRx[3].RxBuffSize > 0)//接纳缓冲区大于0{(UartRx[3].RxBuff)[(UartRx[3].UartRxCnt) ++] = USART1->DR;//将数据存放到缓冲区if(UartRx[3].UartRxCnt == UartRx[3].RxBuffSize)//缓冲区已满{UartRx[3].UartRxCnt = 0;//接纳计数器清零UartRx[3].BuffFull = SET;//缓冲区已满标志} }UartRx[3].NewDataFlag = SET;//收到新数据标志UART_ClearRxInt(3);  //铲除串口接纳中止标志}#endif#if UART_ChMax > 3/************************************************************************************************************************** 函数 :  void UART5_IRQHandler (void)* 功用 :  UART5中止接纳函数* 参数 :  无* 回来 :  无* 依靠 :  底层宏界说* 作者 :  陈鹏* 时刻 :  20110611* 最终修正时刻 : 20120403* 阐明 : 无*************************************************************************************************************************/void UART5_IRQHandler (void){if((UART5->SR & BIT2)  (UART5->SR & BIT1))//假如NE = 1发送噪声过错  //假如FE = 1,发送帧过错{if(UART5->SR);if(UART5->DR);//复位NE操作序列}else if(UartRx[4].RxBuffSize > 0)//接纳缓冲区大于0{(UartRx[4].RxBuff)[(UartRx[4].UartRxCnt) ++] = USART1->DR;//将数据存放到缓冲区if(UartRx[4].UartRxCnt == UartRx[4].RxBuffSize)//缓冲区已满{UartRx[4].UartRxCnt = 0;//接纳计数器清零UartRx[4].BuffFull = SET;//缓冲区已满标志} }UartRx[4].NewDataFlag = SET;//收到新数据标志UART_ClearRxInt(4);  //铲除串口接纳中止标志}#endif#undef UART_ChMax
//USART.H/**************************************************************************************************//* USART 通用同步异步串行发送接纳*//* 陈鹏 20110609*/#ifndef _USART_H#define _USART_H#include "system.h"#include "stdio.h"//UART装备相关结构界说typedef struct{  u8 OddEvenVerify;//奇偶校验,奇,偶,无  u8 StopBitWidth;//中止位位宽1,2} UART_Config_TypeDef;//奇偶校验#define UART_VERIFY_NULL 0//无校验#define UART_ODD 1//奇校验#define UART_EVEN 2//偶校验//中止位#define UART_STOP_1BIT 0//一个中止位#define UART_STOP_2BIT 1//2个中止位//相关APIu8 UARTx_Init(u8 ch,u8 SYS_CLK,u32 Speed,u8 RX_Int);//串口初始化u8 UARTx_Config(u8 ch,UART_Config_TypeDef * cfg);  //串口装备void UARTx_SendByte(u8 ch,u8 data); //UART单字节发送void UARTx_TX(u8 ch,u8 *tx_buff,u16 byte_number);  //UART数据发送函数void UARTx_PowerDown(u8 ch); //UART掉电void UARTx_PowerOn(u8 ch); //UART上电u8 GetUartNewFlag(u8 ch); //获取串口新数据标志u8 GetUartRxBuffFullFlag(u8 ch); //获取串口接纳缓冲区满标志u8 GetUartNewData(u8 ch); //获取串口新数据void SetUartRxBuff(u8 ch,u16 RxBuffSize,u8 *RxBuff);//设置串口接纳缓冲区void UARTx_ClearRxInt(u8 ch); //铲除串口接纳中止标志#endif

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/chuanganqi/277421.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部