第二课,2440串口的学习

xiaoxiao2021-02-28  12

注:以下内容学习于韦东山老师arm裸机第一期视频教程

一.uart(Universal ASynchronous Receiver and Transmitter)简介

    1.1 串口的作用

        1.1.1 打印调试信息

        1.1.2 外接各种模块,例如GPS,蓝牙等

    

    1.2 串口使用

        1.2.1 设置波特率

        1.2.2 数据格式(数据位,停止位,校验位,流控)

        

    1.3 串口协议

        假设ARM要发送一个字节给电脑,例如一个字符'A' = 0x41,对应2进制 0100 0001

        

        1.3.1 双方先约定好每一位占据的时间(波特率),假设为1s

        1.3.2 首先arm将TXD引脚拉低,维持1bit(1s)时间

        1.3.3 PC机载低电平开始处计时

        1.3.4 arm根据数据驱动引脚TXD电平,每一位维持1bit(1s)时间,发送8位,称为数据位

                PC机在数据位的中间读取引脚状态

        1.3.5 第7位发送完成之后,发送校验位(奇偶校验位,数据位+校验位中为1的个数是奇数或者偶数)

                                    校验位现在基本用不到了,电子技术很稳定

        1.3.6 最后发出停止位,高电平(可以约定停止位占据的时间)

        

    1.4 逻辑电平

        这些电平对应为逻辑电平,即1,0分别对应多少V,有很多种逻辑电平。

        

        例如TTL/CMOS逻辑电平,12V-3V表示0,-3V-12V表示1,不适合长距离传输

            引入RS232电平适合长距离传输。

        开发板上的电平是TTL电平,电脑上是RS232电平,如果要想连接需要引入电平转换芯片,将TTL电平转换为RS232电平(mini2440)

        对于JZ2440没有使用电平转换芯片,因为很多电脑没有使用串口,串口0直接接usb串口芯片连接电脑.

                                                                串口1,串口2仍然保持TTL电平

        

二.2440串口结构

    2.1 2440串口结构图如下:

         

    2.2 串口发送

        对于2440,我们需要将数据从内存中取出通过串口控制器发送出去,在串口线上我们是逐位发送的。

        2.2.1 因此肯定会有一个移位器对应图的Transmit Shifter

        2.2.2 移位的数据来自于fifo,图中的Transmit Buffer Register,

        2.2.3 而fifo中的数据来自于内存。

    

    2.3 串口接受

        在串口线上接受数据也是逐位接受的

        2.3.1 移位器逐位接受数据

        2.3.2 放入fifo

        2.3.3 程序从fifo中取出数据

    

    2.4 问题-> 如何知道数据/接受发送完毕?

        2.4.1 中断CPU

        2.4.2 查询状态

        

三.Uart编程(具体参考程序代码注释)

    3.1 串口初始化

        3.1.1 配置引脚

              a.配置GPHCON寄存器,配置串口0的TXD,RXD引脚
              b.配置GPHUP寄存器,TXD,RXD上拉,因为起始位是通过拉低电平来表示的
        

        3.1.2 设置波特率

                在2440芯片手册上有如下公式:

          

           我们需要设置UBRDIVn来控制串口的时钟分频得到波特率

                            

        3.1.3 设置数据格式(8n1)

        

    3.2 输出函数

    3.3 接受字符函数

    代码如下:

             #include "uart.h" /* 115200,8n1 */ void Uart0Init() { /* 1.配置引脚 */ /* 1.1 配置GPH2,GPH3用作TXD,RXD */ GPHCON &= ~((0X3 << 2*2) | (0X3 << 2*3)); /* 1.2 配置GPH2,GPH3内部上拉 */ GPHUP &= ~((0x1 <<2) | (0x1 << 3)); /* 2.设置波特率115200 */ /* * 2.1 设置UART clock * UCON0 bit[11:10] = 0, UART clock = PCLK = 50M * UCON0 bit[1:0] = 1, 中断/轮询模式接受 * UCON0 bit[3:2] = 1, 中断/轮询模式发送 */ UCON0 = 0x5; /* 2.2 设置分频系数UBRDIVn * UBRDIVn = (int)(UART clock / (baud * 16)) - 1 * = (int)(PCLK / (115200 * 16)) - 1 * = (int)(50000000 / (115200 * 16)) - 1 = 26; */ UBRDIV0 = 26; /* 3.设置数据格式 */ ULCON0 = 0x3; /* 8n1 */ } void putchar(char c) { while (!(UTRSTAT0 & (1 << 1))); UTXH0 = c; } int getchar() { while (!(UTRSTAT0 & (1 << 0))); return URXH0; } void puts(const char *s) { while (*s) { putchar(*s); s++; } }       

    测试代码如下:

#include "uart.h" int main() { char c; Uart0Init(); puts("Hello, World!\n"); while (1) { c = getchar(); if(c == '\n') putchar('\r'); if(c == '\r') putchar('\n'); putchar(c); /* 回显输入语句 */ } return 0; }
转载请注明原文地址: https://www.6miu.com/read-2350266.html

最新回复(0)