2.3.2.5 IMX6ULL特殊的地方
Daisy Chain select IMX6ULL还有一个“Daisy Chain select”功能,
比如下图中: A、B、C三个引脚都可以连接到Module X,它们都可以驱动Module X。
使用哪一个引脚呢?还需要设置“Daisy Chain
select”,用来选择A、B、C之一。
Daisy Chain Select有什么用处呢? 比如UART,它只有TXD、RXD两个引脚:RXD有外部电路输入。
能否让UART的TXD直接给RXD提供数据?可以!这就是回环,方便调试。 怎么做?
可以在外部电路把TXD接到RXD,也可以在芯片内部让RXD可以选择数据来源,如下图所示:
UART1_RX的输入选择
2.3.3 设置串口参数
2.3.3.1 设置波特率
波特率算公式:
上述公式中,Ref Freq为80MHZ,BUMR和UBIR在寄存器中设置。
要先设置UBIR,再设置BUMR
UBIR、BUMR中的值,是实际值减1
2.3.3.2 设置数据格式
比如数据位设置为8,无校验位,停止位设置为1。
2.3.3.3 IMX6ULL芯片要求必须设置
对于UART1_UCR3的bit2,必须设置为1,芯片要求的,没什么道理可讲:
2.3.4 根据状态寄存器读写数据
2.3.4.1 状态寄存器
2.3.4.2 接收数据寄存器
读这个寄存器,就可读取串口数据,如下图:
2.3.4.3 发送数据寄存器
2.3.4 寄存器地址
其他寄存器地址 用到的寄存器,从C代码定义如下:
volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA ; volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA ; volatile unsigned int *IOMUXC_UART1_RX_DATA_SELECT_INPUT ; volatile unsigned int *CCM_CSCDR1; volatile unsigned int *CCM_CCGR5; IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA = (volatile unsigned int *)(0x20E0084); IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA = (volatile unsigned int *)(0x20E0088); IOMUXC_UART1_RX_DATA_SELECT_INPUT = (volatile unsigned int *)(0x20E0624); CCM_CSCDR1 = (volatile unsigned int *)(0x020C4024); CCM_CCGR5 = (volatile unsigned int *)(0x020C407C);
UART1寄存器
UART1基地址:0x02020000,里面的寄存器用结构体来表示比较方便:
/*根据IMX6ULL芯片手册<<55.15 UART Memory Map/Register Definition>>的3608页,定义UART的结构体,*/ typedef struct { volatile unsigned int URXD; /**< UART Receiver Register, offset: 0x0 串口接收寄存器,偏移地址0x0 */ unsigned char RESERVED_0[60]; volatile unsigned int UTXD; /**< UART Transmitter Register, offset: 0x40 串口发送寄存器,偏移地址0x40*/ unsigned char RESERVED_1[60]; volatile unsigned int UCR1; /**< UART Control Register 1, offset: 0x80 串口控制寄存器1,偏移地址0x80*/ volatile unsigned int UCR2; /**< UART Control Register 2, offset: 0x84 串口控制寄存器2,偏移地址0x84*/ volatile unsigned int UCR3; /**< UART Control Register 3, offset: 0x88 串口控制寄存器3,偏移地址0x88*/ volatile unsigned int UCR4; /**< UART Control Register 4, offset: 0x8C 串口控制寄存器4,偏移地址0x8C*/ volatile unsigned int UFCR; /**< UART FIFO Control Register, offset: 0x90 串口FIFO控制寄存器,偏移地址0x90*/ volatile unsigned int USR1; /**< UART Status Register 1, offset: 0x94 串口状态寄存器1,偏移地址0x94*/ volatile unsigned int USR2; /**< UART Status Register 2, offset: 0x98 串口状态寄存器2,偏移地址0x98*/ volatile unsigned int UESC; /**< UART Escape Character Register, offset: 0x9C 串口转义字符寄存器,偏移地址0x9C*/ volatile unsigned int UTIM; /**< UART Escape Timer Register, offset: 0xA0 串口转义定时器寄存器 偏移地址0xA0*/ volatile unsigned int UBIR; /**< UART BRM Incremental Register, offset: 0xA4 串口二进制倍率增加寄存器 偏移地址0xA4*/ volatile unsigned int UBMR; /**< UART BRM Modulator Register, offset: 0xA8 串口二进制倍率调节寄存器 偏移地址0xA8*/ volatile unsigned int UBRC; /**< UART Baud Rate Count Register, offset: 0xAC 串口波特率计数寄存器 偏移地址0xAC*/ volatile unsigned int ONEMS; /**< UART One Millisecond Register, offset: 0xB0 串口一毫秒寄存器 偏移地址0xB0*/ volatile unsigned int UTS; /**< UART Test Register, offset: 0xB4 串口测试寄存器 偏移地址0xB4*/ volatile unsigned int UMCR; /**< UART RS-485 Mode Control Register, offset: 0xB8 串口485模式控制寄存器 偏移地址0xB8*/ } UART_Type; UART_Type *uart1 = (UART_Type *)0x02020000;
3.IMX6ULL UART编程
/*根据IMX6ULL芯片手册<<55.15 UART Memory Map/Register Definition>>的3608页,定义UART的结构体,*/ typedef struct { volatile unsigned int URXD; /**< UART Receiver Register, offset: 0x0 串口接收寄存器,偏移地址0x0 */ unsigned char RESERVED_0[60]; volatile unsigned int UTXD; /**< UART Transmitter Register, offset: 0x40 串口发送寄存器,偏移地址0x40*/ unsigned char RESERVED_1[60]; volatile unsigned int UCR1; /**< UART Control Register 1, offset: 0x80 串口控制寄存器1,偏移地址0x80*/ volatile unsigned int UCR2; /**< UART Control Register 2, offset: 0x84 串口控制寄存器2,偏移地址0x84*/ volatile unsigned int UCR3; /**< UART Control Register 3, offset: 0x88 串口控制寄存器3,偏移地址0x88*/ volatile unsigned int UCR4; /**< UART Control Register 4, offset: 0x8C 串口控制寄存器4,偏移地址0x8C*/ volatile unsigned int UFCR; /**< UART FIFO Control Register, offset: 0x90 串口FIFO控制寄存器,偏移地址0x90*/ volatile unsigned int USR1; /**< UART Status Register 1, offset: 0x94 串口状态寄存器1,偏移地址0x94*/ volatile unsigned int USR2; /**< UART Status Register 2, offset: 0x98 串口状态寄存器2,偏移地址0x98*/ volatile unsigned int UESC; /**< UART Escape Character Register, offset: 0x9C 串口转义字符寄存器,偏移地址0x9C*/ volatile unsigned int UTIM; /**< UART Escape Timer Register, offset: 0xA0 串口转义定时器寄存器 偏移地址0xA0*/ volatile unsigned int UBIR; /**< UART BRM Incremental Register, offset: 0xA4 串口二进制倍率增加寄存器 偏移地址0xA4*/ volatile unsigned int UBMR; /**< UART BRM Modulator Register, offset: 0xA8 串口二进制倍率调节寄存器 偏移地址0xA8*/ volatile unsigned int UBRC; /**< UART Baud Rate Count Register, offset: 0xAC 串口波特率计数寄存器 偏移地址0xAC*/ volatile unsigned int ONEMS; /**< UART One Millisecond Register, offset: 0xB0 串口一毫秒寄存器 偏移地址0xB0*/ volatile unsigned int UTS; /**< UART Test Register, offset: 0xB4 串口测试寄存器 偏移地址0xB4*/ volatile unsigned int UMCR; /**< UART RS-485 Mode Control Register, offset: 0xB8 串口485模式控制寄存器 偏移地址0xB8*/ } UART_Type; void delay(volatile int d) { while(d--); } int main(void) { uart_init(); while(1) { c=getchar(); putchar(c); putchar(c+1); } return 0; } void uart_init(void) { volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA ; volatile unsigned int *IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA ; volatile unsigned int *IOMUXC_UART1_RX_DATA_SELECT_INPUT ; volatile unsigned int *CCM_CSCDR1;//设置总时钟 volatile unsigned int *CCM_CCGR5; IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA = (volatile unsigned int *)(0x20E0084); IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA = (volatile unsigned int *)(0x20E0088); IOMUXC_UART1_RX_DATA_SELECT_INPUT = (volatile unsigned int *)(0x20E0624); CCM_CSCDR1 = (volatile unsigned int *)(0x020C4024); CCM_CCGR5 = (volatile unsigned int *)(0x020C407C); UART_Type *uart1 = (UART_Type *)0x02020000; /*设置uart总时钟 *uart_clk_root=80mhz */ *CCM_CSCDR1 &= ~((1<<6)|(0X3f));//阅读芯片手册,是重点。 /*给UART模块提供时钟 *UART1_CLK_ENABLE */ *CCM_CCGR |=(3<<24); /*配置引脚功能*/ *IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA &= ~0xf; *IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA &= ~0xf; /*imu6ull特殊的设置*/ IOMUXC_UART1_RX_DATA_SELECT_INPUT |= 3;//将数据设置pc模式,而不是设置回环模式。 /*设置波特率 *115200=80M/(16*(UBMR+1)/(UBIR+1)) *UBIR=15 *115200 = 80M/(UBMR+1) *UBMR = 80,000,000/115200=694 *真正的波特率=80000000/694=115274 */ uart1->UBIR=15; uart1->UBMR = 694; /*设置数据格式*/ uart1->UCR2 = (0<<8) | (0<<6) | (1<<5) |(1<<2) |(1<<1); /*IMX6ULL芯片要求设置*/ uart1->UCR3 |= (1<<2); /*使能UART*/ uart1->UCE1 |=(1<<0); } int getchar(void) { UART_Type *uart1 =(UART_Type *)0x02020000; while((uart1->USR2 & (1<<0))==0); return uart1->URXD; } int putchar(char c) { UART_Type *uart1 = (UART_Type *)0x02020000 while ((uart1->USR2 & (1<<3))==0); uart1->UTXD =c; return c; }