分享

stm32的一个UART应用

 Aaronwy 2011-12-27

 
001 /**********************************************************************
002 Name: STM32_UART.c
003 DESC: STM32的通用串口配置
004 Author: 戒往 QQ:8926785
005 Copyright: http://
006 ***********************************************************************/
007 #include "Board_Driver.h"
008  
009 /*******************************************************************************
010 * Function Name  : USART1_Init
011 * Description    : USART1的初始化
012 * Input          : None
013 * Output         : None
014 * Return         : None
015 *******************************************************************************/
016 void USART1_Init(void)
017 {
018 GPIO_InitTypeDef USART1_GPIO;                    //GPIO类型结构定义
019 USART_InitTypeDef USART_InitStructure;           //串口设置恢复默认参数
020 NVIC_InitTypeDef NVIC_InitStructure;
021  
022 memset( (void*)&gCommCtrl, 0, sizeof(COMM_CTRL) );  //初始化gCommCtrl中的内存值
023  
024 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA
025                       |RCC_APB2Periph_AFIO  ,ENABLE);
026                                                  //使用USART1与GPIOA的时钟
027                                                  //至于RCC_APB3Periph_AFIO有没必要不知道
028 //GPIO的设置
029 USART1_GPIO.GPIO_Pin=(GPIO_Pin_9);               //PA9是TX
030 USART1_GPIO.GPIO_Speed=GPIO_Speed_50MHz;         //蛋痛.为神马GPIO还要有个最快时钟
031 USART1_GPIO.GPIO_Mode=GPIO_Mode_AF_PP;           //NND,这个AF_PP弄得哥心碎啊,卡了几天,原来模式错了
032 GPIO_Init(GPIOA, &USART1_GPIO);                  //设置
033  
034 USART1_GPIO.GPIO_Pin=(GPIO_Pin_10);              //PA10是RX
035 USART1_GPIO.GPIO_Mode=GPIO_Mode_IN_FLOATING;     //RX,还是有外接10K上拉,所以开漏输入模式
036 GPIO_Init(GPIOA, &USART1_GPIO);                  //再设置
037  
038  
039 //初始化参数设置
040 USART_InitStructure.USART_BaudRate = 115200;                  //波特率115200
041 USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //字长8位
042 USART_InitStructure.USART_StopBits = USART_StopBits_1;        //1位停止字节
043 USART_InitStructure.USART_Parity = USART_Parity_No;           //无奇偶校验
044 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
045                                                               //无流控制
046 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
047                                                               //打开Rx接收和Tx发送功能
048 USART_Init(USART1, &USART_InitStructure);                     //初始化
049 //USART_ITConfig(USART1, USART_IT_TC, ENABLE);               //STM32对发送中断支持十分拉圾.不能在初始化里启动
050 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);               //初始化时只使能RX,不然一上电就会进入中断
051 USART_Cmd(USART1, ENABLE);                                    //启动串口
052  
053 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);              //配置为全部为响应级的中断
054                                                              //这样相当于ARM7中的只有IRQ,没有FIQ??
055 /* Enable the USARTy Interrupt */
056 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;            //这个值找了半天才找到
057 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;           //优先级 0
058 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;              //使能中断
059 NVIC_Init(&NVIC_InitStructure);                              //进行配置
060 }
061  
062  
063  
064 /*******************************************************************************
065 * Function Name  : USART1 IRQ Handler
066 * Description    : USART1 中断例程
067 * Input          : None
068 * Output         : None
069 * Return         : None
070 *******************************************************************************/
071 void USART1_IRQHandler(void)
072 {
073 u8 tmpIdx;
074 u8 tmpChar;
075     /*     接收中断处理   */
076 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
077   {
078     tmpChar= USART_ReceiveData(USART1);         //取出数据,同时也是清除中断标记
079     tmpIdx = gCommCtrl.rxHead;                  //取出当前buff的头指向
080     CommRxBuff[ tmpIdx ] = tmpChar;             //把数据放到buff头里面
081     tmpIdx = (tmpIdx + 1) % COMM_RXBUFF_LEN;    //buff头指向++
082     if( gCommCtrl.rxTail != tmpIdx ) gCommCtrl.rxHead = tmpIdx; //如果缓冲区满,则无法保存下一次接收到的数据
083   }
084  
085  
086     /*     发送中断处理   */ 
087 if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
088   {
089   tmpIdx = gCommCtrl.txTail;
090   if( tmpIdx == gCommCtrl.txHead )                      //buff尾=头 发送完成
091     {
092     USART_ITConfig(USART1, USART_IT_TXE, DISABLE);      //禁止发送中断
093     RS_TX_BUSY = 0;
094     }
095   else
096     {
097     USART_SendData(USART1, CommTxBuff[ tmpIdx ]);       //发送指向buff尾的那个数据
098     gCommCtrl.txTail = (tmpIdx + 1) % COMM_TXBUFF_LEN;  //buff尾指向++
099     RS_TX_BUSY = 1;
100     }     
101   }
102 }
103  
104 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
105 // 【CommPutch】通讯串口发送数据缓冲
106 //      此函数仅缓冲数据,具体发送同发送逻辑执行
107 //
108 // 【参数表】
109 //      u8  txChar    被发送的字节
110 //
111 // 【返回值】
112 //      u8      0: 缓冲区满
113 //              1: 缓冲成功
114 //____________________________________________________________________________
115 u8 CommPutch( u8 txChar )
116 {
117     u8 tmpHead;
118  
119     tmpHead = (gCommCtrl.txHead + 1) % COMM_TXBUFF_LEN;
120     if( tmpHead == gCommCtrl.txTail ) return 0;
121     CommTxBuff[ gCommCtrl.txHead ] = txChar;
122     gCommCtrl.txHead = tmpHead;
123      
124     USART_ITConfig(USART1, USART_IT_TXE, ENABLE);      //使能发送中断就会立即产生一个发送中断.
125     return 1;                                          //当发送缓冲里的数据发送完成后,在中断中进行屏蔽发送中断
126 }
127  
128 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
129 // 【commCheckRx】通讯串口接收数据检测
130 //      此函数仅检测有无数据,具体读取由commGetch函数执行
131 //
132 // 【参数表】
133 //
134 // 【返回值】
135 //      INT08S      0: 无接收数据
136 //                  1: 有接收数据
137 //____________________________________________________________________________
138 u8 commCheckRx(void)
139 {
140     if( gCommCtrl.rxHead != gCommCtrl.rxTail ) return 1;
141  
142     return 0;
143 }
144  
145 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
146 // 【commGetch】通讯串口读取数据
147 //      只有commCheckRx函数返回成功后才可以调用本函数。
148 //      否则将破坏接收缓冲区。
149 //
150 // 【参数表】
151 //
152 // 【返回值】
153 //      INT08U      读取的数据
154 //____________________________________________________________________________
155 u8 commGetch(void)
156 {
157     u8 rtnChar;
158  
159     // 一定要先取出数据,才能更新数组尾标
160     rtnChar = CommRxBuff[ gCommCtrl.rxTail ];
161     gCommCtrl.rxTail = (gCommCtrl.rxTail + 1) % COMM_RXBUFF_LEN;
162  
163     return rtnChar;
164 }
165  
166 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
167 // 【commSendStr】通讯串口发送字符串
168 //     
169 // 【参数表】
170 //      pStr        被发送字符串地址,字符串以0x00结尾。
171 //
172 // 【返回值】
173 //      无
174 //____________________________________________________________________________
175 void commSendStr( u8* pStr )
176 {
177     u8 txChar;
178  
179     while(1)
180     {
181         txChar = *pStr++;
182         if( txChar == 0 ) break;
183         while( 0 == CommPutch( txChar ) );
184     }
185  
186     return;
187 }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多