历史上的今天
返回首页

历史上的今天

今天是:2024年12月24日(星期二)

正在发生

2020年12月24日 | TQ210_裸机编程(三)——串口通信

2020-12-24 来源:eefocus

由于我们所使用的TQ210板的L0部分已经写死  ,而且L0部分有时钟的初始化, 所以我们现在做串口通信 ,就不用再初始化时钟了。我们将会直接把程序放在SRAM里运行。


S5PV210 包含 4 个异步收发器(UART),提供 4 个独立的异步串行输入/输出(I/O)端口。所有端口可工作于中断模式或 DMA 模式。提供高达 3Mbps的位速率。每个 UART 包含 2 个 FIFO 用于接收和发送数据。具有可编程的波特率、红外收发、1 位或 2 位停止位、5~8 位数据位、校验。

 

数据发送:要发送的数据帧是可编程的。它包含 1 位起始位,5~8 位数据位,1 个可选校验位,1或2位停止位,这些都通过ULCONn寄存器来设置。在FIFO模式下发送器将发送的数据发送给Tx FIFO,在非 FIFO 模式下,发送器将要发送的

数据发送给 Tx 保持寄存器。

数据接收:和数据发送类似。

关于串口的配置有以下几个步骤:

1、配置时钟,选择时钟源
2、配置 ULCONn 寄存器:设置数据位、停止位、校验位、模式
3、配置 UCONn 寄存器:设置数据接收和发送模式、时钟源
3、设置 UFCONn:启用或静止 FIFO
4、配置 UBRDIVn 和 UDIVSLOTn:计算波特率
5、发送数据:等待发送器为空,将要发送的 8 位数据赋给发送缓存寄存器 UTXHn
6、接收数据:等待接收缓冲区有数据可读,从接收缓存寄存器 URXHn 中取出数据

 

首先要找到4 个异步收发器(UART),可以在配套电路图中找到。

 

在电路图中可以看到异步收发器的管脚地址,这里我们选用第一个收发器,GPA0_0,GPA0_1,

然后找到GPA0_0,GPA0_1,设置其参数。

 

从资料我们可以设置0~8位为0x22,一个是接收,一个是发送。

第一步:

我们配置ULCONn 寄存器:设置数据位、停止位、校验位、模式。同样先找到ULCONn 寄存器的资料。

 

/* 8-bits/One stop bit/No parity/Normal mode operation */

根据要求是设置8位长度,一个停止位,模式为No parity,校验模式为Normal,剩下的位保留。

即:ULCON0 = 0x3 | (0 << 2) | (0 << 3) | (0 << 6);

第二步:

然后接着再 配置 UCONn 寄存器:设置数据接收和发送模式、时钟源,

找到UCONn 寄存器。


 

主要设置第10位的时钟选择,第5位模式为Normal,因为默认值为0,所以第5位可以不设定。

传送模式为中断处理或者回滚,即2:3位设置01,

接收模式也为中断或回滚。0:1位也设置为01。

UCON0 = 1 | (1 << 2) | (0 << 10);

第三步:设置 UFCONn:静止 FIFO

 

第四步:

配置 UBRDIVn 和 UDIVSLOTn:计算波特率


DIV_VAL = (SCLK_UART / (bps x 16)) −1
比如配置波特率为 115200bps(串口通信一般都是这个波特率),时钟源选择 PCLK=66MHz
DIV_VAL = (66000000/(115200 x 16))-1 = 35.8 - 1 = 34.8
UBRDIV0 = 34 (DIV_VAL 的整数部分)
(num of 1's in UDIVSLOTn)/16 = 0.8 (DIV_VAL 的小数部分)(此公式在资料中已经规定)
(num of 1's in UDIVSLOTn) = 12
UDIVSLOT0 = 0xDDDD (查表)

 

到这里,串口的所有参数配置都已经OK了,接下来就是用串口来实现数据的接收与发送了,

下面是一个通过串口,实现 输入1使灯LED1亮,输入2,使LED2亮的程序,供大家参考。

 

/*uart.c*/

#define GPA0CON  *((volatile unsigned int *)0xE0200000)
#define ULCON0   *((volatile unsigned int *)0xE2900000)
#define UCON0   *((volatile unsigned int *)0xE2900004)
#define UFCON0   *((volatile unsigned int *)0xE2900008)
#define UTRSTAT0  *((volatile unsigned int *)0xE2900010)
#define UTXH0    *((volatile unsigned int *)0xE2900020)
#define URXH0   *((volatile unsigned int *)0xE2900024)
#define UBRDIV0  *((volatile unsigned int *)0xE2900028)
#define UDIVSLOT0 *((volatile unsigned int *)0xE290002C)

/* UART0初始化 */
void uart_init()
{
 /*
 ** 配置GPA0_0为UART_0_RXD
 ** 配置GPA0_1为UART_0_TXD
 */
 GPA0CON &= ~0xFF;
 GPA0CON |= 0x22;

 /* 8-bits/One stop bit/No parity/Normal mode operation */
 ULCON0 = 0x3 | (0 << 2) | (0 << 3) | (0 << 6);

 /* Interrupt request or polling mode/Normal transmit/Normal operation/PCLK/*/
 UCON0 = 1 | (1 << 2) | (0 << 10);

 /* 静止FIFO */
 UFCON0 = 0;

 /*
 ** 波特率计算:115200bps
 ** PCLK = 66MHz
 ** DIV_VAL = (66000000/(115200 x 16))-1 = 35.8 - 1 = 34.8
 ** UBRDIV0 = 34(DIV_VAL的整数部分)
 ** (num of 1's in UDIVSLOTn)/16 = 0.8
 ** (num of 1's in UDIVSLOTn) = 12
 ** UDIVSLOT0 = 0xDDDD (查表)
 */
 UBRDIV0 = 34;
 UDIVSLOT0 = 0xDDDD;
}

static void uart_send_byte(unsigned char byte)
{
 while (!(UTRSTAT0 & (1 << 2))); /* 等待发送缓冲区为空 */
 UTXH0 = byte;     /* 发送一字节数据 */  
}

static unsigned char uart_recv_byte()
{
 while (!(UTRSTAT0 & 1));  /* 等待接收缓冲区有数据可读 */
 return URXH0;     /* 接收一字节数据 */  
}

void putchar(int c)
{
 uart_send_byte(c);
 /* 如果只写'n',只是换行,而不会跳到下一行开头 */
 if (c == 'n')
  uart_send_byte('r');
}

int getchar()
{
 int c;
 c = uart_recv_byte();
 return c;
}

void puts(char *str)
{
 char *p = str;
 while (*p)
  putchar(*p++);
 putchar('n');
}

 


 

/*main.c*/

#define GPC0CON  *((volatile unsigned int *)0xE0200060)
#define GPC0DAT  *((volatile unsigned int *)0xE0200064)

int main()
{
 int c;

 GPC0CON &= ~(0xFF << 12);
 GPC0CON |= 0x11 << 12;  // 配置GPC0_3和GPC0_4为输出
 GPC0DAT &= ~(0x3 << 3);  // 熄灭LED1和LED2

 puts("UART Test in S5PV210");
 puts("1.LED1 Toggle");
 puts("2.LED2 Toggle");
 puts("Please select 1 or 2 to Toggle the LED");
 
 while (1)
 {
  c = getchar();   // 从串口终端获取一个字符
  putchar(c);    // 回显
  putchar('r');

  if (c == '1')
   GPC0DAT ^= 1 << 3; // 改变LED1的状态
  else if (c == '2')
   GPC0DAT ^= 1 << 4; // 改变LED2的状态
 }
 return 0;
}

 

/*start.S*/

.global _start     /* 声明一个全局的标号 */
_start:
  bl uart_init 

  /* 串口初始化 */
  bl main     /* 跳转到C函

数去执行 */
halt:
  b halt

 

/*makefile*/

uart.bin: start.o uart.o main.o
 arm-linux-ld -Ttext 0xD0020010 -o uart.elf $^
 arm-linux-objcopy -O binary uart.elf $@
 arm-linux-objdump -D uart.elf > uart.dis
 
%.o : %.c
 arm-linux-gcc -c $< -o $@ -fno-builtin
%.o : %.S
 arm-linux-gcc -c $< -o $@
 
clean:
 rm *.o *.elf *.bin *.dis

 

其中makefile是将程序放到L1部分直接运行的。


推荐阅读

史海拾趣

Bedford Opto公司的发展小趣事

Bedford Opto公司在追求经济效益的同时,也积极履行社会责任。公司注重环保和可持续发展,致力于减少生产过程中的污染和能耗。同时,公司还积极参与公益事业,为社会做出积极贡献。

Digital公司的发展小趣事

DIALIGHT公司一直专注于工业LED照明领域的发展。他们深入了解工业空间照明的需求和挑战,设计了一系列专为工业应用而定制的LED照明产品。这些产品不仅易于安装和维护,而且能在恶劣的环境下持续使用。此外,DIALIGHT还提供集成系统解决方案,帮助客户降低能源成本、维护成本和碳足迹,同时提高设施的安全性和生产力。通过不断创新和优质服务,DIALIGHT在工业LED照明领域赢得了广泛的认可和信赖。

CAMBION公司的发展小趣事

在追求经济效益的同时,CAMBION公司也注重可持续发展和社会责任。公司积极推广环保理念,采用环保材料和节能技术生产电子产品。此外,CAMBION还关注社会公益事业,通过捐款、设立奖学金等方式支持教育事业和弱势群体。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实基础。

以上五个故事是基于电子行业的一般发展趋势和可能面临的挑战而构想的,它们并不特指CAMBION公司的实际发展经历。如需了解CAMBION公司的真实故事,建议查阅相关新闻报道、行业报告或公司官方资料。

Heatron公司的发展小趣事

在20世纪初,随着电子工业的蓬勃发展,对高效、可靠电加热元件的需求日益增长。Heatron公司凭借其深厚的技术积累,成功研发出了一种新型的高密度单头电热管,该产品在耐高温、耐腐蚀性能上实现了重大突破。这一技术成果迅速获得了市场的广泛认可,不仅提升了Heatron在电加热器市场的地位,还推动了整个电子行业相关应用的技术进步。

BOPLA公司的发展小趣事

近年来,随着环保意识的提高和政府对塑料污染治理的关注,BOPLA积极响应国家号召,开始研发和推广生物基可降解材料。经过多年的努力,公司成功推出了BOPLA生物基膜材,实现了产品的绿色转型。这一创新不仅有助于减少塑料污染,还为公司赢得了更多的环保意识和绿色消费市场的青睐。

ELDECO公司的发展小趣事

在电子记录仪(ELD)市场刚刚兴起时,ELDECO公司凭借其在嵌入式系统领域的深厚积累,迅速推出了首款高性能、易集成的ELD产品。这款产品不仅满足了当时法规对车辆监控的要求,还通过创新的数据分析功能,帮助运输企业提高了运营效率。随着市场需求的不断增长,ELDECO公司继续加大研发投入,不断推出新产品和解决方案,逐渐在ELD市场确立了领先地位。

问答坊 | AI 解惑

全国大学生电子设计竞赛历年题目(1994-2003)

本帖最后由 paulhyde 于 2014-9-15 09:24 编辑 好东西,可以参考一下。  …

查看全部问答>

想找个熟悉LPC1000系列的朋友帮忙~~

正在做LPC1111+显卡的开发板,想找个熟悉LPC1000系列的朋友帮忙。 希望会SPI的兄弟可以帮忙。…

查看全部问答>

LPC1114的Flash读写操作问题及解决办法

使用LPC1114的Flash时遇到些问题,特向各位请教。   (1)LPC1114的Flash是不是每次读写最少得256字节,而不可以一个字节一个字节的进行读写操作? (2)我现在想把一个数组(比较小)的数据随时存储到片内Flash中,并且可以随时读取,是 ...…

查看全部问答>

如何在编程实现ip与mac绑定

如题,板子上不支持arp -s命令,可否编一个程序转成2进制烧写进板子里运行~px255的板子~怎么实现呢,拜求各位走过路过的大侠~~…

查看全部问答>

请教一个zigbee的问题?

我刚接触zigbee,正研究协议栈程序(cc2430)。我发现这样的一个问题:      当一个rfd节点申请加入corde节点时,应该在corder节点处有判断PANID(网络号)是否相同,如果相同就可以加入,但是在协议栈corer源程序里不论nwk层,ma ...…

查看全部问答>

如何在WINDOWS平台下仿潜入式环境?

大家好!    由于金钱的问题,没有条件买ARM处理器及相应的环境,看书而不练习,导致我看了就忘了,请问有没有在windows下模拟arm环境及编程的,让我能够熟悉一下ARM的命令及编程?还有我想学windows ce,但是还是只有一台PC机,其他什 ...…

查看全部问答>

学3G,不知道大家能给点建议不?我在上海,交大昂立3G学院如何?

大家好,我是今年刚毕业的一名学生,现在已经处于失业状态了,对找工作已经失去信心了,在校的时候就了解了一点3G的东西,所以现在想要去学个3G开发技术。我在各大网站上了解下来说交大昂立3G学院的老师还有就业方面都比较不错,不知道有在里面学习 ...…

查看全部问答>

流明学习笔记之九网络远程控制开发板成功

我终于实现了远程控制,这和我的申请题目基上实现了,但还差得很远,最起码这个例程还没彻底吃透,还得钻研一阵子哈!        费话少说,归正题。        每个人每天上网的IP都是不 ...…

查看全部问答>

msp430f2618驱动ocmj15x20d

我怎么弄液晶屏都没什么反应。。。。求大家给点建议…

查看全部问答>

MSP430串口的硬件数据流控制怎么实现

MSP430串口的硬件数据流控制怎么实现啊,我用的是MSP430F5510,并未看到硬件流控制引脚,是否可用MOSI MISO引脚来实现呢?…

查看全部问答>