ARM第四天(蜂鸣器下、串口)

蜂鸣器
buzzer.h

#ifndef __BUZZER_H__
#define __BUZZER_H__

#define GPC0CON (*((volatile unsigned int*)0xE02000A0))
#define GPC0DAT (*((volatile unsigned int*)0xE02000A4))
#define GPC0PUD (*((volatile unsigned int*)0xE02000A8))

#endif

buzzer.c

#include "buzzer.h"

void delay(unsinged int n);
void led_main(void){
   //配置GPD0_1管脚为输出口 操作GPD0CON bit[7,4]为0001
   GPD0CON = (GPD0CON & 0xFFFFFF0F)|0x00000010;
   //2,禁止GPD0_1管脚内部上下拉电阻 操作GPD0PUD bit[3,2]为00
   GPC1PUD &=~0xC ;
   //3,控制GPD0_1管脚输出高电平和低电平  操作GPD0DAT  bit[1] = 1/0;
   while(1){
      GPD0DAT = 2;
      delay(0x100000);
      GPD0DAT &= ~2;
      delay(0x100000);
   }
}

void delay(unsinged int n){
   while(n){
      n--;
   }
}

Makefile:

PROG=buzzer
BIN=$(PROG).bin
OBJS=buzzer.o

LC=arm-linux-gcc
LD=arm-linux-ld
OBJCOPY=arm-linux-objcopy

LDFLAGS = nostartfiles -nostdlib
-Ttext 0x20008000 -e buzzer_main
CFLAGS=-march=armv5te -nostblib

$(PROG):(OBJS)
        $(LD) $(LDFALGS) -o $(PROG) $(OBJS)
        $(OBJCOPY) -o binary $(PROG) $(BIN)
        cp $(BIN) /fttpboot 
%.o:%.c
    $(CC) $(CFLAGS) -c -o $@ $<
clean:
        rm -vf $(OBJS) $(PROG) $(BIN)

UART 通用串行异步收发器 串口
串行通信:利用一条数据线将数据一位一位的顺序传送,特点是通信线路简单,成本低,适合于长距离传送
并行通信:利用多条数据线将数据的各位同时传送,特点是传输速度快,适合于短距离传送

异步:在 一个字符的传输时间范围内保持同步即可
同步:在数据传输过程中,需要一根时钟线同步,IIC总线、SPI总线

串口通信协议:
发送方 接收方
起始位:数据开始传输的标志,逻辑0(低电平)
数据位:需要传输的有效数据,通常有 5-8bit(5,6,7,8)
奇偶校验位:在数据位后面加上一位表示校验位
奇校验:加上校验位后保证1的个数为奇数
偶校验:加上校验位后保证1的个数为偶数
如:
发送方(8奇校验) 接收方(8奇校验)
1110 0011 0(校验位) 1110 0011 0
计算校验位:0 (相等,正确)

1110 0011 0(校验位) 1010 0011 0
计算校验位:1 (不相等,传输错误)

奇偶检验方法:只能校验1bit的错误
如果通信的 双方按照约定的校验方式计算出校验位与接收到校验位,如果不等:肯定错误;如果相等:不一定正确(只保证校验1bit出错的有效生)

停止位:表示一个字符数据结束的标志,可以是1bit或者是2bit
空闲位:处于逻辑1,表示当前线路无数据传送。

波特率:非常重要的参数,表示数据传输的速率,表示每秒钟传输二进位的个数。一般11520、9600

通信示例:
这里写图片描述

全双工
这里写图片描述

2:RxD 接收管脚
3:TxD 发送管脚
5:SG 接地

EIA电平(串口)
逻辑1:-3V ~ -15V
逻辑0:+3V ~ +15V

TTL电平(TPAD)
逻辑1:+3V ~ +5V
逻辑0:+0V ~ + 0.8V

接收数据:EIA -> TTL
发送数据: TTL -> EIA
电平转换芯片

这里写图片描述

这里写图片描述

这里写图片描述

通过原理图可知:
1,PC机与TPAD的com1相连,使用直通串口线相连,因为,在设计硬件原理图时,已经实现了线路的交叉。
2,PC机与TPAD的com2相连,使用交叉串口线相连。

这里写图片描述
发送管脚复用GPA0_1
接收管脚利用GPA0_0

串口属于全双工通信。

SPV210处理器对于串口收发器:
1,SPV210提供了4个独立的通用串行异步收发器(UART)
2,数据传输可以使用轮询、中断和DAM方式
3,采用系统时钟最大传输速率是3MBps,最常用115.2kbps
4,每个UART通道有两个FIFO(一个接收FIFO、一个发送FIFO)
ch0(256bytes),ch1(64bytes),ch2(16bytes),ch2(16bytes),供发送数据和接收数据,以提高效率
FIFO其实就是相当于缓存器,发送或接收先进缓冲区
5,ch0,ch1,ch2支持自动流控
6,ch0,ch1,ch2,ch3支持红外发送接收
7,一个或两个停止位
8,支持5位,6位,7位,8位有效数据宽度
9,支持奇偶校验

这里写图片描述

1,发送器ch0(TPAD底板上标识成com1)
1),TXD0:发送管脚,复用GPIO管脚的GPA0_1
2),发送寄存器:用于存放CPU需要发送的数据
大小:非FIFO模式 一个字节
FIFO模式 256个字节(每个ch大小不一样)
3),发送移位器:发送缓冲寄存器中的数据并不是直接传送到输出管脚TXD0(GPA0_1),还必须先送到发送移位器中(Transmit shifter),然后再由Transmit shifter 通过移位操作,将数据一位一位的发送到TXD0管脚上。
2,接收器:
1),RXD0:接收管脚,复用GPIO和GPA0_0管脚
2),接收缓冲寄存器:用于存放接收的数据
大小:非FIFO模式 一个字节
FIFO模式 256个字节(每个ch大小不一样)
3),接收移位器:从接收管脚RXD0上接收来的数据并不是直接放到接收缓冲寄存
器 中,而是先一位一位放到移位器中,当收满一个字之后,再放到接收缓冲寄存器中。
3,波特率产生器
发送移位器和接收移位器对数据的发送和接收都是按照波特率产生器产生的波特率的速度进行数据的接收和发送的
时钟源:内部系统时钟 PCLK
外部时钟 SCLK_UART

这里写图片描述

ULCON0:设置数据格式寄存器
UCON0: 串口控制寄存器
UFCON0
UMCON0
UTRSTAT0 状态寄存器
UBRDIV0 设置波特率寄存器1
UDIVSL0T0 设置波特率寄存器2
UTXH0 发送缓冲寄存器
URXH0 接收缓冲寄存器

这里写图片描述
上面的四个寄存器对应四个串口
ULCON0寄存器用寺设置串口通信的数据格式
ULCON0 = 3

UCON0 寄存器
这里写图片描述

UCON0=5
1,数据接收模式,这里采用轮询 bit[1:0]
2,数据发送模式,这里肜轮询 bit[3:2]
3,是否暂停信号,这里采用正常 bit[4]
4,回环模式 ,这里采用正常 bit[5]
5,时钟源选择(PCLK = 66.5MHZ) bit[10]

回环模式

这里写图片描述

UTXH0发送缓冲寄存器:
这里写图片描述

URXH0 接收缓冲寄存器
这里写图片描述

UTXH0 发送缓冲寄存器
URXH0 接收缓冲寄存器

UTRSTAT0 状态寄存器
这里写图片描述

Receive buffer data ready:
bit[0]:
bit[0] = 0,说明接收缓冲寄存器URXH0中还没有收到数据,即使有数据,也不是有效数据
bit[0] = 1,说明接收缓冲寄存器URXH0中已经有有效数据了。
如果要读取接收缓冲寄存器URXH0时,什么时候读?应该先判断UTRSTAT0状态寄存器的bit[0]为1 时,才能读取URXH0寄存器,否则,等待。

Transmit buffer empty:
bit[1]
bit[1]=0,不能向发送缓冲寄存器UTXH0中写数据(因为上一次的数据还没有发出去)
bit[1]=1,可以向发送缓冲寄存器UTXH0中写数据,如果要发送数据,首先先判断状态寄存器UTRSTAT0的bit[1],只有bit[1]为1时,才能向发送缓冲寄存器UTXH0写数据,否则,等待。

数据的收发模式:轮询方式,轮询状态寄存器URTSTAT0的bit[1:0],
发送数据:bit[1] =1, 才能写UTXH0
接收数据:bit[0] =1, 才能读UTXH0
都是在对应bit为1时,才能操作,为0时,等待。

波特率寄存器

这里写图片描述
PCLK = 66.5MZH = 665 00000 HZ
bps = 115200
DIV_VAL = ( 66500000/(115200*16)) -1 = 35.07855
DIV_VAL = UBRDIV + (num of 1’s in UDIVSLOTn)/16
得到
UBRDIVn = 35 整数部份
(num of 1’s in UDIVSLOTn)/16 = 0.07855 小数部份
(num of 1’s in UDIVSLOTn) = 0.07855 * 16 = 1.25694
对该数取整(舍去小数部份),即UDIVSLOTn寄存器的值的1的个数为1,
查表:
这里写图片描述
UDIVSLOTn= 0x0080

ULCON0 = 3 设置数据格式寄存器(校验位、数据宽度。。。。)
UCON0 = 5 设置串口控制寄存器
UFCON0 =0
UMCON0 =0
UBRDIV0 = 35 设置波特率寄存器1
UDIVSLOT0 = 0x0080 设置波特率寄存器2
UTRSTAT0 状态寄存器
UTXH0 发送缓冲寄存器
URXH0 接收缓冲寄存器

案例:
发送数据
TPAD 发送端
PC 接收端,显示在屏幕
思路:
1,配置串口管脚
GPA0_0 接收管脚
GPA0_1 发送管脚
GPA0CON 0XE0200000
这里写图片描述

GPA0PUD 0xE0200008
禁止两个管脚的内部上下拉电阻bit[3:0]
2,配置串口
ULCON0 = 3 设置数据格式寄存器(校验位、数据宽度。。。。)
UCON0 = 5 设置串口控制寄存器
UFCON0 =0
UMCON0 =0
UBRDIV0 = 35 设置波特率寄存器1
UDIVSLOT0 = 0x0080 设置波特率寄存器2
3,编写发送字符的函数

uart.h

#ifndef __UART_H__
#define __UART_H__

#define GPA0CON (*((volatile unsinged int*) 0xE0200000))
#define GPA0PUD (*((volatile unsinged int*) 0xE0200008))

#define ULCON0 (*((volatile unsinged int*) 0xE2900000))
#define UCON0 (*((volatile unsinged int*) 0xE2900004))
#define UFCON0 (*((volatile unsinged int*) 0xE2900008))
#define UMCON0 (*((volatile unsinged int*) 0xE290000C))
#define UTRSTAT0 (*((volatile unsinged int*) 0xE2900010))
#define UTXH0 (*((volatile unsinged int*) 0xE2900020))
#define URXH0 (*((volatile unsinged int*) 0xE2900004))
#define UBRDIV0 (*((volatile unsinged int*) 0xE2900028))
#define UDIVSL0T0 (*((volatile unsinged int*) 0xE290002C))

//声明函数原型
extern void uart0_init(void);
extern void uart0_putc(char c);
extern void uart0_puts(const char *str);

#endif __UART_H__

uart.m

#include "uart.h"

void uart0_init(void)
{
     //1,配置GPA0_0为串口的接收功能
     //操作GPA0CON[3:0] = 0010 RXD
     //2 配置GPA0_1为串口的发送功能
     //操作GPA0CON[7:4]= 0010 TXD
     GPA0CON = (GPA0CON & ~0xFF)|0x22
     //3 禁止内部上下拉电阻
     //操作GPAoPUD[3:0] = 0
     GPA0PUD &= ~0xF;
     //4 配置串口寄存器
     ULCON0 = 3;
     UCON0 = 5;
     UFCON0 = 0;
     UMCON0 = 0;
     UBRDIV0 = 35;
     UDIVSLOT0 = 0x80;
}


void uart0_putc(char c)
{
    //判断状态寄存器UTRSTAT0
    //bit[1] = 0,等待
    //bit[1] = 1,向UTRSTAT0寄存器写数
    while(!(UTRSTAT0 & 0x2))
    {
        ;
    }
    //发送字符
    UTXH0 = c;

}

void uart0_puts(const char *str)
{
    if(str == 0)
    {
        return;
    }
    while(*str)//
    {
        uart0_putc(*str);
        str++;
    }

}

main.c 应用程序测试

#include "uart.h"
void main(void)
{
    //1,初始化串口
    uart0_init();
    //2,发送一个字符串
    while(1){
        uart0_puts("\n URAT0 test!!!!");
    }
}

Makefile

PROG=uart
BIN=$(PROG).bin
OBJS=main.o uart.o 

LC=arm-linux-gcc
LD=arm-linux-ld
OBJCOPY=arm-linux-objcopy

LDFLAGS = nostartfiles -nostdlib
-Ttext 0x20008000 -e main
CFLAGS=-march=armv5te -nostblib

$(PROG):(OBJS)
        $(LD) $(LDFALGS) -o $(PROG) $(OBJS)
        $(OBJCOPY) -o binary $(PROG) $(BIN)
        cp $(BIN) /fttpboot 
%.o:%.c
    $(CC) $(CFLAGS) -c -o $@ $<
clean:
        rm -vf $(OBJS) $(PROG) $(BIN)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值