|
//-------------------------- AHR_USART.C --------------------------------------------------------------9 {! e" ?+ T) x6 R #include "AHR_USART.H"% o) z& t/ k _6 B4 r. I u8 COMBUF[256]="0"; //接收缓冲,最大256个字节' ]% W5 J4 a+ ~7 X2 w; i$ A u8 iComBuf=0;) Y, O r. S4 n u8 ComNow =2; // 为区分5个串口共用一个缓冲区的识别问题而作的标记,显示时用颜色区分2 J6 |7 V1 ^- O: _' j: p) i' v: Y //===================================================================================================== // 直接寄存器操作实现全部串口通信初始化及数据收发:如:US123ART45Init(3,9600,0x0C,2,0,0,0,0);串3优先级27 G0 G8 D: {) ~( ` // TX-串口输出: 1-A9 ;2-A2;3-B10;4-C10;5-C12 //char str[]="4Step:1.RCC;2.AFIO;3.USART;4.NVIC"; // RX-串口输入: 1-A10;2-A3;3-B11;4-C11;5-D2 未完成:NVIC 仍然使用库函数 -- 20180728 -- //----------------------------------------------------------------------------------------------------- const u32 irqNOADcom[5]={37/*0xD4:COM1*/,38/*0xD8:COM2*/,39/*0xDC:3*/,52/*0x110:4*/,53/*0x114:5*/};/ i6 Q( A& a; e+ P% R$ c- w const u32 APB2IO_APB1US23ART45[10]={0x4004,0,0x04,0x20000,0x08,0x40000,0x10,0x80000,0x30,0x100000}; const u32 USART_REGADDR[5]={0x40013800,0x40004400,0x40004800,0x40004C00,0x40005000}; const u32 COMxBaudRate[4]={0xEA6/*9600*/,0x271/*57600*/,0x138/*115200*/,0x08C/*256000*/}; const u32 TXRX_PortSet[5][6]={{0x40010804,0x000000B0,0xFFFFFFBF,0x40010804,0x00000400,0xFFFFF4FF},# P0 I. z* a6 d) N {0x40010800,0x00000B00,0xFFFFFBFF,0x40010800,0x00004000,0xFFFF4FFF}, {0x40010C04,0x00000B00,0xFFFFFBFF,0x40010C04,0x00004000,0xFFFF4FFF}, {0x40011004,0x00000B00,0xFFFFFBFF,0x40011004,0x00004000,0xFFFF4FFF}, {0x40011004,0x000B0000,0xFFFBFFFF,0x40011400,0x00000400,0xFFFFF4FF}}; void US123ART45Init(u8 iCOM,u32 baudRate,u8 Tx8Rx4,u8 priPS,u8 Ds1908,u8 St0115,u8 y1n0CRC,u8 HFr1c2)5 ?( t7 w! e9 |9 z( b% ?3 j9 u$ g { NVIC_InitTypeDef structNVIC; //irqNOADcom[0]=USART1_IRQn; priPS-主副优先级级别(暂定相同)2 H4 E* I& y- ` uint32_t tmpReg=0; //参数Ds1908=1:数据9位,=0:8位;St011522315=0,1,2,3;停止位=1,0.5, 2, 1.5 *(volatile unsigned long *)(0x40021018)|=APB2IO_APB1US23ART45[iCOM*2-2]; //打开 GPIOX 时钟$ E u1 n- m, U3 s- J- i *(volatile unsigned long *)(0x4002101C)|=APB2IO_APB1US23ART45[iCOM*2-1]; //打开U(S)ARTX时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //所有涉及中断必须开放此时钟(外中断皆复用端口) *(volatile unsigned long *)TXRX_PortSet[iCOM-1][0]|=TXRX_PortSet[iCOM-1][1]; // TX0 z3 K) C& o: I& h6 [ *(volatile unsigned long *)TXRX_PortSet[iCOM-1][0]&=TXRX_PortSet[iCOM-1][2]; *(volatile unsigned long *)TXRX_PortSet[iCOM-1][3]|=TXRX_PortSet[iCOM-1][4]; // RX0 ^- A" v* W4 h" z *(volatile unsigned long *)TXRX_PortSet[iCOM-1][3]&=TXRX_PortSet[iCOM-1][5]; tmpReg = *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x10); // 设置 USART_CR2 //--.LINEN.STOP[1:0],CLKEN.CPOL.CPHA.LBCL,--.LBDIE.LBDL.--,ADD[3:0]& m1 J! e9 Z- b0 {! x w tmpReg&=(uint16_t)0xCFFF; // 1 1 0 0 , 1 1 1 1 ,1 1 .... 1 //清STOP if (St0115 != 0) tmpReg |= (St0115 << 12); // 停止位设置0-1;1-.5;2-2 *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x10) = tmpReg; // 将设置写回寄存器CR2 tmpReg = *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x0C); // 设置 USART_CR1: I2 [* l, |% q2 f& i // UE M,WAKE PCE PS PEIE,TXEIE TCIE RXNEIE IDLEIE,TE RE RWU SBK tmpReg&=0xE9F3; // 1 0, 1 0 0 1 , 1 1 1 1 , 0 0 1 1 // 清M等位 if (Ds1908 != 0) tmpReg |=0x00001000; //数据位9位; 缺省 Ds1908=0数据位8位 if (y1n0CRC!= 0) tmpReg |=0x00000400; //偶校验 ; 缺省y1n0CRC=0不校验 if (Tx8Rx4 != 0) tmpReg |=Tx8Rx4; //8-使能Tx模式;4-使能Rx模式;0xC-TxRx全能* e7 ^+ @- U4 R *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x0C) = tmpReg; // 将设置写回寄存器CR1! n2 j& \3 a7 V b4 \; j" z4 k tmpReg = *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x14); // 设置 USART_CR30 X2 u6 a, j: W. z3 Q // CTSIE CTSE RTSE,DMAT DMAR SCEN NACK,HDSEL IRLP IREN EIE4 q' z) i# b6 E, q3 X5 T7 [ tmpReg&=0xFCFF; // 1 0 0 , 1 1 1 1 , 1 1 1 1 //清CTSE/RTSE( ~7 R) F/ N: L if (HFr1c2 != 0) tmpReg |= (HFr1c2 << 8); //HFr1c2 =0-禁止;1-RTS/2-CTS/3-R&CTS硬件流控制使能 *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x14) = tmpReg; // 将设置写回寄存器CR3! f" h% D9 F& ?* f' P3 @/ V switch (baudRate){ //tmpReg = *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x08);7 k. ~: ?% H! Y2 Q case 57600: tmpReg = COMxBaudRate[1]; break; // ^--与下面sprintf()语句结合直接读波特率16进制 case 115200: tmpReg = COMxBaudRate[2]; break; // 如果计算则用到下面两句:+ B$ b; t$ `' c6 x case 256000: tmpReg = COMxBaudRate[3]; break; //tmpReg = (u32)Mantissa <<4; //高12位-整数部分& w, H; {1 M% Z& R0 {! E case 9600: //tmpReg |= (0x0000000F & Fraction); // 低 4位-小数部分 default: tmpReg = COMxBaudRate[0]; break; // v--形成数组再经switch查询,写回波特率寄存器 } //sprintf(str,"baudRate:%8X",tmpReg); LCD_ShowString(10,160,240,180,16,(u8*)str);7 `$ ~; A9 v( ~% Y$ L$ j *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x08) = tmpReg; // 将波特率写入寄存器 *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x0C) |=0x00002000; //使能串口9 W8 m+ a& s) b+ w$ E+ a: m' \ *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x00) &=0xFFFFFFBF; //清除中断标志 *(volatile unsigned long *)(USART_REGADDR[iCOM-1]+0x0C) |=0x00000020; //使能串口接收缓冲非空中断$ x& T8 C0 a+ W structNVIC.NVIC_IRQChannel = irqNOADcom[iCOM-1]; // 串口中断通道 structNVIC.NVIC_IRQChannelPreemptionPriority = priPS; // 不能相同 //抢占优先级 structNVIC.NVIC_IRQChannelSubPriority = priPS; // 不能相同 //子优先级 structNVIC.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能; X% \; |% Q6 A NVIC_Init(&structNVIC); //根据指定参数初始化VIC寄存器 }3 x3 B; D6 `6 R, W! ~ void USART2_IRQHandler(void) { //串口2中断服务程序, switch语句专用于格式化以回车换行结束的ASCii串+ q0 }* t/ q E4 G' W" i% J! K2 G u8 r=0; static u8 i=0; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { //接收中断. {5 M6 c- z, n. R$ D% [ if(ComNow!=2) ComNow=2;' A6 L: y7 H* X8 Q- F* c: u& c& N r=USART_ReceiveData(USART2); //读串2到全局数组 switch (r){ case 0x0A: iComBuf=i; i=0; break;) w( O( k$ ~# f4 X; q case 0x0D: USART_ClearITPendingBit(USART2,USART_IT_RXNE); break; default: COMBUF[i]=r; i++; i&=0xFF; break; // 限制在0~255之间3 S% ?! n% t, C } }. v5 i* O: ?# I {, f# ~ if (USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET) //溢出则必须清零# O, u" l& a# R% \/ ? ]. @1 V { USART_ClearFlag(USART2, USART_FLAG_ORE); USART_ReceiveData(USART2); } }+ {* V# r ]7 q) N void UART5_IRQHandler(void) { // 串口5中断服务程序9 p" H8 {. |" K. h if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(UART5,USART_IT_RXNE); //清除接收中断标志 if(ComNow!=5) ComNow=5; COMBUF[iComBuf]=USART_ReceiveData(UART5); iComBuf++; iComBuf&=0xFF; // 限制在0~255之间 } USART_ClearFlag(UART5,USART_FLAG_TC); } void UART4_IRQHandler(void) { // 串口4中断服务程序# U% Y, J) |( D0 g6 @- W if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(UART4,USART_IT_RXNE); if(ComNow!=4) ComNow=4;9 t$ F1 u2 X5 p/ u' Q B COMBUF[iComBuf]=USART_ReceiveData(UART4); //读串2到全局数组 iComBuf++; iComBuf&=0xFF; // 限制在0~255之间3 [/ m$ G) @# T6 l } USART_ClearFlag(UART4,USART_FLAG_TC);0 L. r8 I0 S4 r7 x' O' l4 r }3 u$ T$ v' t- v# z void USART3_IRQHandler(void) { // 串口3中断服务程序; i3 n6 Y( D! u if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART3,USART_IT_RXNE); if(ComNow!=3) ComNow=3; COMBUF[iComBuf]=USART_ReceiveData(USART3); //读串3到全局数组+ d/ b! ?% b, ]9 K+ z3 f5 k iComBuf++; iComBuf&=0xFF; } USART_ClearFlag(USART3,USART_FLAG_TC); }) N, C7 e+ N% R* X U7 Q void USART1_IRQHandler(void) { // 串口1中断服务程序,收到后随即发出去(为普中开发板而暂时保留)3 |3 l9 l/ ]8 d. [9 I. d9 k* G" S if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){ //接收中断 COMBUF[255] = USART_ReceiveData(USART1); USART_SendData(USART1, COMBUF[255]); while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET); } USART_ClearFlag(USART1,USART_FLAG_TC); }% N6 n8 t( @+ v" ]7 n$ F struct __FILE { int handle; }; FILE __stdout; // 标准库需要的支持函数 _sys_exit(int x) { x = x; } // 定义_sys_exit()以避免使用半主机模式 int fputc(int ch,FILE *p) { // 默认函数在使用 printf函数时自动调用 USART_SendData(USART1,(u8)ch);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);return ch;5 v; c6 f3 a/ s' ` }% _! E P0 J/ Q$ Z //-------------------------------------------- end of AHR_USART.C ------------------------------------- //---------------- AHR_USART.H ------------------------------------------------------------------------ #ifndef __usart_H9 m/ L: _6 h3 g: G U8 C' S9 G #define __usart_H7 z; Q6 }- L* r8 _ #include "aiherong.h"5 \4 M2 l( P$ `0 G: c" [ extern u8 iComBuf; // 接收缓冲区指针+ {6 p/ f4 Y! m# U/ Z+ k extern u8 COMBUF[256]; // 接收缓冲区,最大256个字节 extern u8 ComNow; // 5个COM共用公共接收缓冲区COMBUF,以此区分串口号8 j) r! ^% r% \* U! L8 w; I, D void US123ART45Init(u8 iCOM,u32 baudRate,u8 Tx8Rx4,u8 priPS,u8 Ds1908,u8 St0115,u8 y1n0CRC,u8 HFr1c2);2 a2 E; k2 C( t' j# u3 n #endif: ^ ?- S( ~ Q/ @ //-------------------------------------------- end of AHR_USART.H ------------------------------------ |
微信公众号
手机版
//===================== AiHeRong.H ========================== 2018-0712 ===============================
#include "stm32f10x.h"
#define SYSCLK 72
#define REALADDR(addrNum) *((volatile unsigned long *)(addrNum))5 |( E2 Z1 o/ f- W _, l5 c/ i
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))* {$ V: L! t# ^ z
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //bit-baud is CMSIS 功能 20180426
& s+ ^, u5 q% b
//凡艾和荣编写的工程均包含该文件,包括最典型的宏定义和最广泛的移植要点! 【目标】:所有移植全在此进行!!
#include "AHR_TouchFilm.h"
#include "AHR_SysTick.h" K- }- q k; |7 h2 F8 @
#include "AHR_Lcdtft.h"# p( V! G, _2 W* K/ m
#include "AHR_24Cxx.h". i$ Q! _2 Z2 ]( i4 H+ Y% l3 B# _
#include "AHR_usart.h"8 ~1 y( R T2 Y* Y# j0 K- Q
#include "spi.h"+ e% s! M+ Y1 e+ I! K
// 各模块的依存关系要说明,独立性依次为:->SysTick->LcdTFT,24Cxx->TouchFilm-> ....
#include <stdio.h>% A/ n4 W% G, W( F+ T" O
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <cpu.h>
#include <lib_def.h>9 F/ M3 P+ a/ l, e2 q
#include <lib_ascii.h>
#include <lib_math.h>) K+ ?( |7 t7 k- @+ }+ a
#include <lib_mem.h>
#include <lib_str.h>5 K: O* A) t' P) a
#include <bsp.h>* }& Q/ p5 k* W% @" `4 F
#include <os.h>
int SystemDeviceInit(void); // 为uCOSiii的主函数规范而集中初始化设备 全成功才返回TRUE; 201809229 J# \# y' Z4 r) G* w
// 以下暂时保留: 2018-08-09
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C( |, b) W- k% c2 V: ^
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C+ o; a6 k4 y/ G% K* t a8 }# v8 p
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C- _8 k) k0 r* P6 |- Y
#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C9 _; W# p, L! r. V
#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C
#define GPIOA_IDR_Addr (GPIOA_BASE+ 8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+ 8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+ 8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+ 8) //0x40011408$ }$ w6 f* A: u/ O
#define GPIOE_IDR_Addr (GPIOE_BASE+ 8) //0x40011808
#define GPIOF_IDR_Addr (GPIOF_BASE+ 8) //0x40011A08( [# s; d5 f. N ?0 u
#define GPIOG_IDR_Addr (GPIOG_BASE+ 8) //0x40011E08
//IO口操作,只对单一的IO口! //确保n的值小于16!$ @& V: _" o' Y% j/ Z9 Q
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出 * S9 l5 g- ~' F7 y$ M2 L n
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出 4 T4 w7 b8 c( H. T) s) G3 _8 }
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入 7 |/ r# \) e# F# N
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出 4 U4 A/ O$ k( @2 _
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入 & ^9 Y2 W* d2 t, c$ ^1 ]. v8 A
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出 ! ? \/ H$ o3 p5 g2 a4 E
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入7 M$ L* R" T1 [* Z; f& }# U
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出 * z: X% w6 q; D1 G7 r
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入5 X) @! ~& A4 T. R. M% k( R9 t
//------------------------------------------------------ end of AiHeRong.H ----------------------------
while (USART_GetITStatus(USART2,USART_IT_RXNE)==RESET) //在接收中断之外读全局数组COMBUF
if((REALADDR(USART2_BASE)&0x20)==0) 或 if(USART_GetITStatus(USART2,USART_IT_RXNE)==RESET)0 U/ y7 ?* z' f1 I
for (i=iComBuf;i<N_BUF;i++) {: n4 s2 G& \* ~* |2 g9 ?' z
LCD_ShowChar(i*8,60,(char)COMBUF[i],16,0);
}