UART基本介绍:
通用异步收发器UART他的功能非常强大
我们只使用UART的全双工异步通信功能,使用中断接收数据。
UART_RX:串行数据输入。
UART_TX:串行数据输出。
硬件支持:
连接串口(RS232)实现在超级终端里输入输出
软件支持:
超级终端,teraterm-4.75
1、配置UART,我们使用UART2
(1)设置波特率为115200,设置数据字段长为8字,使用1个停止位,无基偶校验,UART Clock disabled,打开发送和接收使能
以上基本设置使用一个函数进行封装设置:
函数内部实现:
设置数据字段长为8字:UART2->CR1 |= 0x00;
使用1个停止位: UART2->CR3 |= 0x00;
使用基数位校验:UART2->CR1 |= 0x00;
UART Clock disabled、打开发送和接收使能等等
(2)打开接收中断,当接收发生或者溢出发生时候,产生接收中断
(3)UART使能
UART2->CR1 &= (uint8_t)(~0x02);
(4)全局中断使能
enableInterrupts();
总体UART配置函数实现如下代码所示:
1 static void UART2_Config(void)
2 {
3 /* EVAL COM (UART) configuration -----------------------------------------*/
4 /* USART configured as follow:
5 - BaudRate = 115200 baud
6 - Word Length = 8 Bits
7 - One Stop Bit
8 - Odd parity
9 - Receive and transmit enabled
10 - UART Clock disabled
11 */
12 UART2_Init((uint32_t)115200, UART2_WORDLENGTH_8D,UART2_STOPBITS_1, UART2_PARITY_NO,
13 UART2_SYNCMODE_CLOCK_DISABLE, UART2_MODE_TXRX_ENABLE);
14
15 /* Enable the UART Receive interrupt: this interrupt is generated when the UART
16 receive data register is not empty */
17 UART2_ITConfig(UART2_IT_RXNE_OR, ENABLE);
18
19 /* Enable the UART Transmit complete interrupt: this interrupt is generated
20 when the UART transmit Shift Register is empty */
21 UART2_ITConfig(UART2_IT_TXE, ENABLE);
22
23 /* Enable UART */
24 UART2_Cmd(ENABLE);
25
26 /* Enable general interrupts */
27 enableInterrupts();
28 }
UART2_Config
2、UART输出功能
如果直接使用C语言的printf函数,只会在编译器的Terminal-I/O中输出,不会在我们想要的超级终端里面输出,所以需要对输出函数做重定向;
实现每次想要输出的时候,将信息打印到超级终端中,故重定向putchar (int c)函数,在函数内使用UART的传送数据功能就可以了,即将要输出的信息写入UART的数据寄存器
1 #define PUTCHAR_PROTOTYPE int putchar (int c)
2 ...
3 /**
4 * @brief Retargets the C library printf function to the UART.
5 * @param c Character to send
6 * @retval char Character sent
7 */
8 PUTCHAR_PROTOTYPE
9 {
10 /* Write a character to the UART2 */
11 UART2_SendData8(c);
12 /* Loop until the end of transmission */
13 while (UART2_GetFlagStatus(UART2_FLAG_TXE) == RESET);
14
15 return (c);
16 }
3、UART输入功能
输入功能实际上是字符串处理过程的实现,在超级终端中输入内容实际上是在UART的数据寄存器里写内容,所我们只需要去数据寄存器里面读取并处理字符串即可;
处理函数功能
首先我们得定义一个支持终端回显的函数uart_GetStr,其中功能包括:
(1)当有我们在终端里敲键盘的时候会立马有正确的内容显示;
(2)当按下特殊按键的时候会有正确的反应;比如backspace会删除一个字符;return会表示输入完毕进入发送;
(3)对于其他特殊案件处理不了应当屏蔽;比如不想实现delete功能,删除刚刚读入的delete字符,并不会回显;
函数实现:
uart_GetStr传入的第一个参数是指向接收数据数组的指针,第二个参数表示是否允许回显;
几个有用变量:
__IO uint8_t ReciveBuff = 0; //save the current char
uint8_t RxBuffer[32] = {0}; //save the input string
__IO uint8_t RxCounter = 0; //the length of valid string
所以,RxBuffer就是uart_GetStr函数的第一个参数,在uart_GetStr函数内部会对每一个字符进行处理,正确的字符才放入RxBuffer中;
//====================================================================================
2 //Function Name | dbg_GetStr
3 //Description | Get string via UART port.
4 //Input | *p_recv_buff : pointer to receive data buffer
5 // | b_echo_on : echo back on or off
6 //Output | detect terminal(0x0d character) :TRUE or FALSE
7 //Remark |
8 //====================================================================================
9 uint8_t uart_GetStr(uint8_t *p_recv_buff, bool b_echo_on)
10 {
11 uint8_t b_end = 0;
12 int i;
13 static uint8_t len = 0;
14 static uint8_t pos = 0;
15 static uint8_t esc_seq = 0;
16 uint8_t c;
17
18 // Get a character.
19 if((c = ReciveBuff) == 0){
20 return 0;
21 }
22 // echo back
23 if(b_echo_on){
24 printf("%c",c); //show the input
25 }
26
27 //Check
28 switch(esc_seq){
29 // Normal
30 case 0:
31 // Return(Terminate)
32 if(c == 0x0d){
33 p_recv_buff[len] = 0;
34 len = pos = 0; // clear
35 if(b_echo_on){
36 printf("n");
37 }
38 b_end = 1;
39 }
40 // Back Space
41 else if(c == 0x08){
42 if(len){
43 if(b_echo_on){
44 printf(" ");
45 printf("%c",0x08); // BS
46 }
47 len--; // update length info.
48 pos--; // update pos info
49 }
50 }
51 // ESC
52 else if(c == 0x1b){
53 esc_seq = 1;
54 }
55 // DEL
56 else if(c == 0x7f){
57 if(len){
58 DeleteChar(pos, len, &p_recv_buff[0]);
59 len --; // update length info
60 if(b_echo_on){
61 printf("%s",&p_recv_buff[pos]);
62 printf(" ");
63 printf("%c",0x08); // BS
64 // move cursor to character end.
65 for(i = 0; i < len - pos; i++){
66 printf("%c",0x1b); // ESC
67 printf("%c",'[');
68 printf("%c",'D');
69 }
70 }
71 }
72 }
73 // Other
74 else{
75 p_recv_buff[pos] = c;
76 len++; // update length info
77 pos++; // update pos info
78 }
79 break;
80 // ESC SEQ -> 1st
81 case 1:
82 if(c == '['){
83 esc_seq = 2; // Next seq.
84 }
85 else{
86 esc_seq = 0; // not support(to normal)
87 }
88 break;
89 //ESC SEQ -> 2nd
90 case 2:
91 if(c=='D'){
92 if(pos){
93 pos--; // "<-" key
94 }
95 }
96 else if(c=='C'){
97 if(pos < len){
98 pos++; // "->" key
99 }
100 }
101 esc_seq = 0; // To normal
102 break;
103 }
104
105 return (b_end);
106 }
uart_GetStr
uart_GetStr函数值为0或者为1,只有在终端中输入回车时才会返回1,其他情况均返回0;
有了这一特点,我们在使用这个函数的时候,只需要获取返回值,当返回0时,把处理过后的、用户正确输入的字符串打印出来看;
运行流程
(1)当终端中有输入的时候,即数据寄存器不为空,从而触发接收中断;
(2)在接收中断中,我们每次从数据寄存器UART2->DR中读取一个字节,赋值到ReciveBuff;
(3)然后调用uart_GetStr函数,对当前输入字符进行处理;(即每一个输入调用一次处理函数)
(4)将uart_GetStr函数的返回值赋值给RT;
1 INTERRUPT_HANDLER(UART2_RX_IRQHandler, 21)
上一篇:STM8S——Analog/digital converter (ADC)
下一篇:最后一页
推荐阅读
史海拾趣
在1966年,Electro-Mech Components, Inc. (EMC)做出了一个重要的战略决策——在墨西哥北下加利福尼亚州的蒂华纳开设一家制造工厂。这个决定标志着EMC正式进军国际市场,并开始了其在全球范围内的业务布局。蒂华纳工厂的建立为EMC带来了更低的制造成本和更广阔的市场前景。随着工厂规模的逐渐扩大,EMC的产品线也日益丰富,从最初的发光按钮开关逐渐扩展到指示灯和多开关互锁组件等多个领域。
在1966年,Electro-Mech Components, Inc. (EMC)做出了一个重要的战略决策——在墨西哥北下加利福尼亚州的蒂华纳开设一家制造工厂。这个决定标志着EMC正式进军国际市场,并开始了其在全球范围内的业务布局。蒂华纳工厂的建立为EMC带来了更低的制造成本和更广阔的市场前景。随着工厂规模的逐渐扩大,EMC的产品线也日益丰富,从最初的发光按钮开关逐渐扩展到指示灯和多开关互锁组件等多个领域。
ELPIDA公司成立于1999年,是日本在DRAM(动态随机存取存储器)领域的重要企业。它的成立是对当时日本半导体产业的一次重要整合,由NEC、日立、三菱电机等公司的DRAM业务合并而成。这一举措旨在振兴日本在DRAM领域的竞争力,并保护国内DRAM产业。
随着智能手机市场的迅猛发展,CMS看到了新的机遇。公司投入大量研发资源,成功开发出一款专为智能手机设计的超低功耗芯片。这款芯片不仅性能卓越,而且能够有效延长手机的续航时间。CMS通过与多家知名手机厂商合作,将这款芯片广泛应用于各类智能手机中,从而迅速打开了市场。
为了配合全球业务的发展,ENERGIZER在亚太地区设立了8个厂房和18个国家的办事处。其中,劲量(中国)有限公司于1992年开始进驻中国,并在1998年在天津设立了生产工厂。这一举措不仅促进了中国与国际间的技术交流与合作,还为中国的电池制造业带来了新的发展机遇。随着中国市场的不断扩大,ENERGIZER在中国的业务也逐渐壮大,成为了中国电池市场的重要参与者。
在ARM公司的支持下,Keil公司不断进行技术创新和产品升级。其中最具代表性的是Keil C51集成开发环境的推出。这一产品不仅继承了Keil PK51的优点,还在性能、稳定性和易用性等方面进行了大幅提升。Keil C51的推出,极大地满足了市场对嵌入式系统开发的需求,也进一步巩固了Keil公司在行业内的领先地位。
有哪位大侠实现过wince iimage组件的encoder 目前小弟困在IImageEncoder::GetEncodeSink( IImageSink** sink) 的实现上, 小弟是先CreateNewBitmap 一个bitmap然后queryinterface 得到imagesink, 但是不知道CreateNewBitmap 中的 width, & ...… 查看全部问答∨ |
|
我用dsPIC30F2012做一个A/D转换,正参考电压接在Vref+上,负参考电压接在Vref-上,VCC经过滤波后接在了AVDD上,现在AVss不知如何处理,因为要求转换的电压是有负电压的,我能不能直接将AVss接地。A/D转换的参考电压选用的是Vref+和Vref-。请前辈高 ...… 查看全部问答∨ |
|
北京微芯力科技术有限公司欢迎来电咨询:010-51581828010-51581825QQ:709357905EMAIL:casperwei@yeah.net… 查看全部问答∨ |
|
选择HSI做为主时钟,16MHz void CLK_Init(void) { CLK_DeInit(); CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); } //SPI初始化 void SPI_MyInit(void) { SPI_DeInit(); ...… 查看全部问答∨ |
|
------------------------------------------------------------------------------- Readme file for LaunchPadFirmwareUpdater2.0.exe LaunchPadFirmwareUpdater2.0.exe is a GUI based utility to update the emulator firmware of Texas Ins ...… 查看全部问答∨ |
以前编程序,用到数学公式中的三角函数,开方函数..公式的时候,自己使用泰勒展开并取到5阶.以前的IQmath用在DSP上比较多,许多的使用文档都是基于TMS320F281xx处理器的,现在好像IQmath能用在LM3S芯片上.麻烦问下TI专家,IQmath如何使用,其中的cmd文件如 ...… 查看全部问答∨ |
设计资源 培训 开发板 精华推荐
- 新突破!超高速内存,为英特尔至强6性能核处理器加速
- 将vRAN站点整合至单服务器,助力运营商降低总体拥有成本
- Allegro MicroSystems 在 2024 年德国慕尼黑电子展上推出先进的磁性和电感式位置感测解决方案
- 左手车钥匙,右手活体检测雷达,UWB上车势在必行!
- 狂飙十年,国产CIS挤上牌桌
- 神盾短刀电池+雷神EM-i超级电混,吉利新能源甩出了两张“王炸”
- 浅谈功能安全之故障(fault),错误(error),失效(failure)
- 智能汽车2.0周期,这几大核心产业链迎来重大机会!
- 美日研发新型电池,宁德时代面临挑战?中国新能源电池产业如何应对?
- Rambus推出业界首款HBM 4控制器IP:背后有哪些技术细节?