IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【蓝桥杯单片机国赛 第十届】 -> 正文阅读

[嵌入式]【蓝桥杯单片机国赛 第十届】

做题思路

首先写上要做的模块,界面,晓得细节
一页纸就能让你不用看pdf即可写出整套题这种
简单示范:

首先smg

void smg()
{
	P2 = (P2&0x1f)|0xc0; P0 = T_COM[smg_i]; P2 = (P2&0x1f);
	P2 = (P2&0x1f)|0xe0; P0 = ~table[smg_i]; P2 = (P2&0x1f);
	smg_i++;
	smg_i &= 0x07;
}

长短矩阵按键

我的思路:

  • 首先先把状态机一次按键写出(用于去抖动)
  • 在一次按键的基础上,检测按键按下(无抖动的一次按键下) 到松开,所花的时间是否大于950ms
  • 最后赋值(是否*10)来区别长短按键
bit flag_changan; //此标志位表示按键是否按下状态,
//以此为标志来计时,当按键松开时,在进行判断长短按键后,记得将计数值清零
void tm1_isr() interrupt 3 using 1
{
    if (count-- == 0)               //1ms * 1000 -> 1s
    {
        count = 1000;               //reset counter
    }

		if(flag_changan) {key_count++;} else key_count = 0;
}
u8 key_scan()
{
	u8 key_return = 99, key = 99;
	h1 = 1; h2 = 1; h3 = 1; h4 = 1;
	l1 = 1; l2 = 1; l3 = 0; l4 = 1;
	if(h3 != 1) key = 13;
	if(h4 != 1) key = 12;
	h1 = 1; h2 = 1; h3 = 1; h4 = 1;
	l1 = 1; l2 = 1; l3 = 1; l4 = 1;
	if(h3 != 1) key = 17;
	if(h4 != 1) key = 16;
	switch(key_state)
	{
		case 0: if(key != 99) key_state = 1; flag_changan = 0; break;
		case 1: if(key == 99) key_state = 0; 
		        else{key_val = key; key_state = 2; flag_changan = 1; } break; //以此判断是否有抖动,若无抖动,开始计时,并记录键值
		case 2: if(key == 99) {  if(key_count>980) key_return =  key_val*10;   //changan
                             else  key_return =  key_val;    
                             key_state = 0;  flag_changan = 0; } //状态2主要判断按键是否松开,若松开就可以判断计时长短,否则一直停留此状态。
            break;   //每按一次键就计时
	return 		key_return;											 
	}

串口收发问题

一般我们使用串口1和串口2,而用于串口1的定时器可以是T0,也可以是T2
但要注意,串口1的中断使能为EA = 1;
而串口2的中断使能为IE2 = 1;
然后在使用isp自动生成波特率代码时要注意咯,在本题中由于定时器0超声波计时(12分频),定时器1用于1ms中断,控制所用程序的一个计时,故我们串口就用定时器2记得区分串口中断!(记得勾选上)
在这里插入图片描述
在这里插入图片描述

首先附上标准代码

void Uart_Isr() interrupt 4 using 1
{
	u8 a,i;
    if (RI)
    {
        RI = 0;             //Clear receive interrupt flag
        a = SBUF;          //P0 show UART data
			  receive[rcv] = a;
			  rcv++;
    }
    if (TI)
    {
        TI = 0;             //Clear transmit interrupt flag
        busy = 0;           //Clear transmit busy flag
    }
}

串口重定向:用printf("");来发送字符串
printf("%d",t);可以发送变量
记得加头文件#include<stdio.h>

char putchar(char c)   //串口重定向
{
	ES=0;			//关串口中断
	SBUF=c;			
	while(TI!=1);	//等待发送成功
	TI=0;			//清除发送中断标志
	ES=1;			//开串口中断
	return c;
}

在上位机发送命令小例子
字符 ‘’
字符串 “”
注意下述代码放在while函数里哟,不能放在中断~~~原因在最底部

				 if(rcv>2&&	receive[rcv-2] == '\r' && receive[rcv-1] == '\n') 
				 {
					 rcv = 0;
				for (i = 0;i <8;i++)
					{
						receive[i] = '\0';
					}
				 }
				if(receive[0] == 'S' && receive[1] == 'T') {printf("the Temp is %d ℃\n\t",t);}

DS18B20

特别好写,for延时12次。在这里插入图片描述
最后也只用写这么点代码就可以读温度啦
首先定义变量
然后初始化
然后skip rom
然后转换温度
转换温度记得要延时一会(若还是读不出来就要关中断啦)
然后我们要读温度啦,继续初始化
然后skip rom
然后先读低再度高
将所读的加起来16位数据右移4位(*0.0625)就是真实温度,但考虑到小数不方便,直接我们放大100倍得u16
最后记得要返回温度哟

u16 r_t()
{
	u8 l,h;
	u16 temp;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(20);

	init_ds18b20();	
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	l = Read_DS18B20();
	h = Read_DS18B20();
	temp = ((u16)h<<8|l)*6.25;
	return temp;
}

超声波

记得跳线帽要插好,不然就是一直99(害)
超声波的思路就是通过发送8个脉冲 {TX = 1;延时 TX = 0; 延时}(8个)
发送8个是为了超声波能够接受回数据
然后打开定时器0(初始化定时器0时记得清空TL0,TH0 以及 12分频)
while(TF0 != 1 && RX != 0 ); //注意这个为&&,两个同时满足才会一直等待
while语句来记录接收到信号的时间,如果没有接收到就会溢出,我们直接写distance = 99 即可。
同时记得数据初始化,方便下一次的定时计数。

void sendsonic()
{
	u8 i;
	for(i=0;i<8;i++)
	{
		TX = 1;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
		TX = 0;
		somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;somenop;
	}
}
void r_distance()
{
	sendsonic();
	TR0 = 1; //counter0 start count
	while(TF0 != 1 && RX != 0 ); //注意这个为&&,两个同时满足才会一直等待
	TR0 = 0;
	if(RX == 0) 
	{
		distance = (TH0*256+TL0)*0.017;
		TL0 = 0;
	    TH0 = 0;
	}
	else 
	{distance = 99;	
		TF0 = 0;
		TL0 = 0;
	    TH0 = 0;
	}
}

AT24c02

这个也是照着新派呢手册打代码,记得DAC输出电压通道是0x40
并且读取eeprom的数据要延时5ms,不然会有问题,只需要在前面加就行啦

	 Delay5ms()	;
	 index_change = at24_r(0x55);
	 at24_w(0x55,++index_change);
void at24_w(u8 add,u8 dat)
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

u8 at24_r(u8 add)
{
	u8 temp;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();

		IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
  temp = IIC_RecByte();
	IIC_Stop();
	return temp;
}

最后串口的问题

在这里插入图片描述
在代码1中,你想在串口中断里发送一堆数据??
串口中断似乎一次智能处理一个字符,而你想用printf发字符串,显然寄了
所以还是安心放在while函数里吧!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:46:35  更:2022-03-22 20:47:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:46:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码