嵌入式学习——硬件(UART)——day55

1. UART

1.1 定义

        UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一种用于串行通信的硬件设备或模块。它的主要功能是将数据在串行和并行格式之间进行转换。UART通常用于计算机与外围设备或嵌入式系统之间的数据传输。

1.2 特点

  1. 异步通信:UART不需要发送和接收设备之间的时钟信号同步,数据传输速率和传输格式(如起始位、数据位、校验位、停止位)在通信双方事先协商好。

  2. 全双工通信:UART可以同时进行数据的发送和接收。

  3. 串行数据传输:数据一位一位地传输,减少了连线数量,但需要更多的时间来传输数据。

  4. 组成部分

    • 发送器(Transmitter):将并行数据转换为串行数据并发送出去。
    • 接收器(Receiver):接收串行数据并将其转换为并行数据。

1.3 代码

#include <s3c2440.h>
#include <string.h>
#include <stdio.h>
#include "led.h"
#include "key.h"
#include "interrupt.h"
#include "delay.h"
#include "pwm.h"
#define ADDRESS 0X08

void init_wdt(void)	//初始化看门狗,禁止启动,关闭看门狗
{
	WTCON &= ~(1 << 0);
}

void init_clk(void)
{
	unsigned int t = MPLLCON; //将PCLK频率存入变量设置好再进行修改,防止频率修改中途器件因为频率过高而短路
	t &= ~((0xff << 12) | (0x3f << 4) | (3 << 0)); //利用锁相环将12MHz倍频
	t |= ((127 << 12) | (2 << 4) | (1 << 0)); //配置fclk频率大约为400Mhz
	CLKDIVN |= ((2 << 1) | (1 << 0));//分频,配置HCLK为100MHz,HCLK为50MHz	
	MPLLCON = t;//将所有频率配置好再进行设置,防止器件被烧坏
}

unsigned char buffer[128];//存储pc给s3c2440发送,s3c2440接收到的字符串
unsigned char tmpbuffer[128];
unsigned int pos;//已经收到字符的个数,下一个要收到字符的位置

void uart0_handler(void)
{
	if (SUBSRCPND & (1 << 0))//如果UART0接收到了数据
	{
		buffer[pos++] = URXH0;			
	}
	SUBSRCPND = SUBSRCPND;	
}

void init_uart0(void)
{
	unsigned int t = 0;

	GPHCON &= ~(0x0f << 4);
	GPHCON |= ((2 << 6) | (2 << 4));//设置中断模式,串口电路引脚寄存器功能

	t = ULCON0;		//9600 n 8 1 波特率? 校验位? 数据位? 停止位
	t &= ~(1 << 6);//不使用红外模式
	t &= ~(7 << 3);//无奇偶校验
	t &= ~(1 << 2);//每帧 1 个停止位
	t |= (3 << 0);//每帧用于发送或接收的数据位的个数8位
	ULCON0 = t;

	t = UCON0;	 //s3c2440给电脑发送数据用轮询   电脑给s3c2440发送数据,s3c2440接收数据触发中断
	t &= ~(3 << 10);//选PCLK给 UART 波特率
	t &= ~(3 << 8);//发送接收方式改为脉冲方式
	t &= ~(0x0f << 4);// 都设置为普通模式
	t &= ~(0x0f << 0);
	t |= (0x05 << 0);//设置UART模式发送轮询  接收模式为中断
	UCON0 = t;

	INTSUBMSK &= ~(1 << 0);//uart子中断改为可服务状态
	enable_irq(IRQ_UART0);//配置中断为IRQ模式,让中断处于可服务模式	  //配置接收的中断
	register_irq(IRQ_UART0 ,uart0_handler);

	UBRDIV0 = 325;//波特率分频寄存器 50000000/9600/16-1约等于325
	pos = 0;		 	 
}

void uart_send_char(unsigned char ch)
{
	UTXH0 = ch;	// UART0 要发送的数据   UART 发送缓冲 寄存器
	while (0 == (UTRSTAT0 & (1 << 2)));//数据发完的标志   UART TX/RX 状态 寄存器	
}

void send_buffer(const char *p, unsigned int len)
{
	unsigned int i = 0;

	for (i = 0; i < len; ++i)
	{
		uart_send_char(*p++);	
	}
}

int parse(const char *p, unsigned int len)//分析上位机pc端发送的信息
{
	int i = 0;
	int n = 0;
	unsigned char tmpnum = 0;

	if (p[0] != 0xaa || p[len-1] != 0x0D)//判断起始校验位
	{
		n = 0;
	}
	if (p[1] != ADDRESS) //判断是否为正确的下位机
	{
		n = 0;
	}

	for (i = 0; i < 8; i++)
	{
		tmpnum += p[i];
	}
	if (p[8] != tmpnum)	 //判断校验位是否正确
	{
		n = 0;
	}

	if (0x01 == p[2])//调频
	{
		n = 1;
	}
	else if (0x02 == p[2]) //点灯
	{
		n = 2;
	}
	
	return n;	
}

int main(void)
{
	float f = 0;
	int ret = 0;
	int i = 0;
	unsigned led = 0;
	init_wdt();
	init_led();
	init_clk();
	init_delay();
	init_uart0();
	init_pwm0();
	while (1)
	{
		if (pos != 0)//收到数据了
		{
			mdelay(100);//让数据接收完成, 若收100字节,即1000比特,要1000/9600=0.1s=100ms
			ret = parse((const char *)buffer, pos);
			if (1 == ret)//调频	  AA 08 01 04 00 00 00 3F F6 0D
			{
				buffer[8] = '\0';
				f = *((float *)buffer[4]);
				set_duty_ratio(f);
				buffer[8] = 0xf6;

				for (i = 0; i < 3; i++)
				{
					tmpbuffer[i] = buffer[i];					
				}
				tmpbuffer[3] = 0x01;
				tmpbuffer[4] = 0x01;
				tmpbuffer[5] = buffer[8];
				tmpbuffer[6] = buffer[9];
				tmpbuffer[7] = '\0';
				send_buffer((const char *)tmpbuffer, 7);
			}
			else if (2 == ret)//点灯	AA 08 02 04 00 00 00 3F B9 0D
			{
				buffer[8] = '\0';
				led = buffer[7];
				ledon(led);
				buffer[8] = 0xB9;

				for (i = 0; i < 3; i++)
				{
					tmpbuffer[i] = buffer[i];					
				}
				tmpbuffer[3] = 0x01;
				tmpbuffer[4] = 0x01;
				tmpbuffer[5] = buffer[8];
				tmpbuffer[6] = buffer[9];
				tmpbuffer[7] = '\0';
				send_buffer((const char *)tmpbuffer, 7);	
			}
			else //发送失败
			{
				for (i = 0; i < 3; i++)
				{
					tmpbuffer[i] = buffer[i];					
				}
				tmpbuffer[3] = 0x00;
				tmpbuffer[4] = 0x00;
				tmpbuffer[5] = buffer[8];
				tmpbuffer[6] = buffer[9];
				tmpbuffer[7] = '\0';
				send_buffer((const char *)tmpbuffer, 7);		
			}
			pos = 0;
			memset(buffer, 0, sizeof(buffer));
			memset(tmpbuffer, 0, sizeof(tmpbuffer));						 
		}
	}
}

1. TCON   2 定时器输出变相开关  0刚开始低电平、  1刚开始低电平

2. 串口是一种串行

串行不一定是串口

串行:一次收发一个比特

3. 传一个字节,8位+1位起始位+1位停止位,传输一个字节即传输十个比特

9600波特率为一秒传输960个字节

9600  n   8   1

波特率  校验位  数据位  停止位

U17作用:将TTL转化为标准RS232

4. UART控制寄存器

TX RX

脉冲:数据收发完产生中断

电平:数据收发过程中产生中断

5. i++和++i(++i效率高)

        若i = 2;

++i printf打印i和++i都是2+1=3

i++(会开辟临时变量保存i++) printf打印i为3,i++为2

6. PC端(电脑)上位机

板子下位机

7. CRC校验算法

8. modbus

成功01失败00

1. 计数器监视寄存器查看计数器从开始减到目前的数字,查看当前的数字减到了多少

modbus重点!!!!!!!!!!!CRC

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值