ARM学习笔记--day08

uart
    串口通信
    学习一般步骤:
        1.弄懂原理
            a.通信格式,数据
                串口控制器与处理器相连接,然后控制器与数据线相连接,有9根线,一根rx,一根tx
                怎么保证数据没有错,两点决定:
                    a.通信速率,必须保证接收/发送双方的发送速率是一致的(波特率一致),否则会导致接收的数据不对,还是很好理解的;115200是每秒传输的位数1s传递10k数据
                    b.数据位(实际数据,长度位8);
                    校验位(校验前边数据是否正确,1位),保证前边的数据尽可能的正确,奇校验与偶校验,用一个位去校验前边的数据是否正确,奇校验(O)查前边逻辑0是奇数个就是1,偶数个就是0,同理偶校验(E)就反过来,偶数个就是1,奇数个就是0,如果有一位出错就可以校验出来;不校验(N)
                    停止位(1位或者2位),就是传一组数据,停一下让你响应一会,然后再传下一组数据,停止位长度,1位停止位,就是空出一个传一位的时间让对方响应
            b.原理图
                关心2,3管脚,RXD0,TXD0就是数据收发线,然后连接到一个芯片上SP3232EEN芯片,就是电压转换的,经过这个芯片转换为TTL电平,ARM是TTL电平,原理图芯片两边,左边是输入芯片的关键,经过芯片右边的就是转换电平之后的管脚,然后经过找原理图找到核心板的对应管脚,然后根据核心板的原理图中的管脚,在芯片手册中找到这个管脚的相关寄存器控制,XuRXD0/GPA0
            c.怎么通过控制器控制
                复用管脚,先配置成串口,然后再看串口控制器的控制方法
                1.先配置GPA0CON[1]寄存器配置成0010就是uart的发送管脚,先配置GPA0CON[0]寄存器配置成0010就是uart的接收管脚,0与1代表着管脚
                2.GPIO复用其他功能的时候,上下拉电阻通常是关掉的,所以GPA0PUD[0]与GPA0PUD[1]应该全为0,就把上下拉电阻关掉了
                以上已经配置成UART的功能了
                然后根据芯片手册找到UART的章节,看看具体的控制器编程方法
                相关寄存器:
                    ULCON0(线控寄存器,控制线路上数据传输的格式):
                        bit0~1(Word Length):设定串口传递的数据长度
                        bit2(Number of Stop Bit):设定串口传递停止位个数
                        bit3~5(Parity Mode):设定串口传递校验模式
                        bit6(Infrared Mode):设定串口传递红外模式(通信媒介是否是采用红外线的模式),是否使用红外模式
                    UCON0(控制器,控制器本身的控制寄存器):
                        bit0~1(Receive Mode):接收模式
                            01:中断方式/查询方式(polling方式,就是死循环读数据)
                            10:DMA模式(直接内存访问,能够访问内存,通常内存只能由CPU读写,但是DMA模式,就是让DMA控制器来访问内存,这样就不需要CPU去亲自搬运数据了,然后加快了速率,CPU会告诉DMA控制器,从哪搬运数据,板运数据到哪,搬运多少数据,搬运完成后DMA通知CPU,已经搬运到内存中了,CPU使用吧,通常用于大数据的传输的场景)
                        bit2~3(Transmit Mode):传输模式
                            方式与接收方式相同
                        bit4(Send Break Signal ):特殊场景下,发送这一位,会打断原有的通信
                            00:正常模式
                        bit5(Loop-back Mode):回路模式,自己发走的数据,对方不接收,自己再接收一下,用回路模式测试,硬件是否发送接收有无问题
                            00:正常模式
                        bit6~9中断相关的,6出错是否触发中断,7超时触发,8中断触发方式
                        bit10(Clock Selection):数字电路中的时钟是驱动一切东西的根源,类似于人的心跳,时钟的来源是时钟控制器,负责发给每一个模块时钟
                            时钟控制器提供两个时钟:PCLK与SCLK_UART,uboot决定了时钟是哪个,uboot初始化的时候选择时钟,初始化内存,等等工作
                    UFCON0(UART的FIFO):等价于发送/接收缓冲,,先进先出,有FIFO的,缓冲满了后一起发送出去或接收过来,如果不是FIFO,就来一个数据发一次或接收一次,有FIFO在传输大数据的时候还是可以提高效率的
                配置波特率的寄存器:
                    UBRDIV0(配置波特率,主要配置波特率的寄存器):这个值芯片手册会提供具体的算法,首先要明确咱们所要的波特率,作为一个参数带入公式计算一下就得到这个值,将这个值给到这个寄存器的低16位
                    UDIVSLOT0(微调的寄存器,频率特别低的时候可以不配置这个寄存器):将UBRDIV0这个值的小数部分*16,将这个整数与芯片手册提供的表格进行对比,得出一个数,给到这个寄存器就是微调的数据
                发送数据:
                    通过处理器(CPU),把数据送给Transmit Buffer Register,之后硬件会将数据从这个寄存器中给到Transmit shift移位器,然后这个移位器将数据给到TX管脚发给外设,这个移位器是由波特率产生器控制,然后移位器按照设定的波特率来发送速率
                    由于串口控制器的波特率低于处理器的速度,所以发送出去的速度与CPU给给到寄存器的速度相比,要满,所以要查询寄存器是否为空,需要不停查询,直到空了,再往里边放数据,这就是实际项目中,通常发出串口数据后,要加延时,这个查询就引出UTRSTAT0这个寄存器,需要查询这个寄存器,bit2位,Transmitter empty 为1代表整个寄存器空了,bit1位,Transmit buffer empty 为1代表buffer为空,可以往里存数据,发送数据有UTXH0这个寄存器,0~7位,就存储要发送的数据
                接收数据:
                    方法同上
        2.实验,写一个shell,实现收发字符
            start.s
                .global start@为了让.c看得到    
            start:
                bl uart_run    @没有赋值,说明uart_run没有参数
                b .            @b .是死循环
            uart.c
                char shell_buffer[256];
                void uart_init(void){
                    配置寄存器,就是操作地址
                }
                char getc(void){
                    volatile int *b = (int *)0xe2900010;
                    //1.查看状态
                    while(!(*b&0x1)){
                        //2.读出字符
                        b = (int *)0xe2900024;
                        return (char)*b;
                    }
                }
                void putc(char a){
                    volatile int *b = (int *)0xe2900010;
                    //1.查看状态
                    while(!(*b&0x2)){
                        //2.写入字符
                        b = (int *)0xe2900024;
                        (char)*b = a;
                    }
                }
                void puts(char* s){
                    
                }
                void gets(void){
                    int i = 0;
                    while(1){
                        if((shell_buffer[i] != '\r')&&(i<256)){    //输入回车结束,'\r'是回车
                            shell_buffer[i] = getc();    //获取输入的指令
                            putc(shell_buffer[i]);        //这里是为了在终端显示
                            i++;
                        }else{
                            if(shell_buffer[i] == '\r'){
                                shell_buffer[i] = '\0';
                            }else{
                                /*do nothing*/
                            }
                            break;
                        }
                    }
                }
                void parse_cmd(void){
                    char cmd_buffer[5] = "test";
                    for(int i=0;((shell_buffer[i] != '\0')&&(i<5));i++){
                        if(shell_buffer[i] != cmd_buffer[i]){
                            puts("cmd is error");
                            break;
                        }else{
                            do_test_cmd();//硬盘上的一段程序,通常需要shell进程去做这个函数的处理
                        }
                    }
                }
                void uart_run(void){
                    uart_init();
                    while(1){
                        char a = getc();
                        putc(a);
                        puts("##");
                        gets();
                        parse_cmd();
                    }
                }
        shell结构:首先是一个循环,第一步获取输入的命令,第二步分析命令,第三步执行命令,第四步结束运行等待下次输入的命令
            shell有提示符:实现打印字符串,但是不打回车
nandflash存储器编程方法

时钟

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值