一.设备间通讯
- 单线
- 双线 uart (全双工 异步)
- 双线 i2c (半双工 同步)
- 三线 spi (全双工 同步)
- 并行通讯 多根数据线 地址线,如内存
二.串口通讯协议
三. 串口内部机制
四.串口编程
1.初始化
管脚设置为UART模式
串口协议设置(奇偶校验为,数据位等)
串口波特率设置
2.发送字符
发送状态判断
发送
3.接收字符后环回
接收状态判断
接收
五.汇编 c语言混合编程
Makefile进行编译,连接脚本进行链接。
all:
arm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o start.o start.S
arm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o main.o main.c
arm-none-linux-gnueabi-ld start.o main.o -Tmap.lds -o uart.elf
arm-none-linux-gnueabi-objcopy -O binary uart.elf uart.bin
arm-none-linux-gnueabi-objdump -D uart.elf > uart.dis
clean:
rm -rf *.bak start.o main.o uart.elf uart.bin uart.dis
脚本map.lds
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") //指定文件格式
OUTPUT_ARCH(arm)
ENTRY(_start) //连接之后的第一个地址是_start
SECTIONS
{
. = 0x40008000; /*指定链接的起始地址 */
. = ALIGN(4);
.text : //代码段开始
{
start.o(.text) //入口start.s
*(.text) //系统自动指定其他函数
}
. = ALIGN(4);
.data : // 数据段开始
{ *(.data) }
. = ALIGN(4);
.bss :
{ *(.bss) }
}
start.s(汇编部分)
.global delay1s
.text
.global _start
_start:
b reset @0x00
ldr pc,_undefined_instruction @0x04
ldr pc,_software_interrupt
ldr pc,_prefetch_abort
ldr pc,_data_abort
ldr pc,_not_used
ldr pc,_irq
ldr pc,_fiq
_undefined_instruction: .word _undefined_instruction
_software_interrupt: .word _software_interrupt
_prefetch_abort: .word _prefetch_abort
_data_abort: .word _data_abort
_not_used: .word _not_used
_irq: .word _irq
_fiq: .word _fiq
reset:
ldr r0,=0x40008000 @设置异常向量表的启始地址为 0x40008000
mcr p15,0,r0,c12,c0,0 @ Vector Base Address Register
init_stack:
ldr r0,stacktop /*get stack top pointer*/
/********svc mode stack,为c函数的调用提供栈空间********/
mov sp,r0
sub r0,#128*4 /*512 byte for irq mode of stack*/
/****irq mode stack**/
msr cpsr,#0xd2
mov sp,r0
sub r0,#128*4 /*512 byte for irq mode of stack*/
/***fiq mode stack***/
msr cpsr,#0xd1
mov sp,r0
sub r0,#0
/***abort mode stack***/
msr cpsr,#0xd7
mov sp,r0
sub r0,#0
/***undefine mode stack***/
msr cpsr,#0xdb
mov sp,r0
sub r0,#0
/*** sys mode and usr mode stack ***/
msr cpsr,#0x10
mov sp,r0 /*1024 byte for user mode of stack*/
b main //设置完栈后,跳转到C的main函数
delay1s:
ldr r4,=0x1ffffff
delay1s_loop:
sub r4,r4,#1
cmp r4,#0
bne delay1s_loop
mov pc,lr
.align 4
/**** swi_interrupt handler ****/
stacktop: .word stack+4*512
.data
stack:
.space 4*512
.end
main.c
/*
功能: 实现通过串口com3 输出字符显示
1. 看电路图找到CPU对应的控制管脚 GPA1_5 GPA1_4
2. 看芯片手册,找到对应寄存器
a. 配置管脚为串口模式
b. 功能块设置
3. 编程
*/
#define GPA1CON (*(volatile unsigned int *)0x11400020)
#define ULCON3 (*(volatile unsigned int *)0x13830000)
#define UCON3 (*(volatile unsigned int *)0x13830004)
#define UBRDIV3 (*(volatile unsigned int *)0x13830028)
#define UFRACVAL3 (*(volatile unsigned int *)0x1383002C)
#define UTXH3 (*(volatile unsigned int *)0x13830020)
#define UTRSTAT3 (*(volatile unsigned int *)0x13830010)
void uart_init(void)
{
//-----外: 配置管脚的工作模式
GPA1CON |= 0x220000; //配置GPA1_5 GPA1_4 为uart串口模式
//-----内: 功能块设置
//1. uart 通讯协议格式的设置
ULCON3 = 0x03; //设置协议格式( 无校验位 1个停止位 8个数据位)
UCON3 = 0x05; //设置串口发送接收模式为polling模式
/*2. 设置uart 的速度为115200
DIV_VAL = (100000000/(115200 *16)) - 1 = 53.253
UBRDIVn = 53
UFRACVALn/16 = 0.253
Therefore, UFRACVALn = 4
*/
UBRDIV3 = 53;
UFRACVAL3 = 4;
}
void putc(char c)
{
while(1)
{
if(UTRSTAT3&0x02) //检测发送是否为空
{
break;
}
}
UTXH3 = c; //发送字符
}
int main(void)
{
uart_init();
while(1)
{
putc('f');
delay1s(); //调用汇编中的1s延时
}
return 0;
}