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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 蓝桥杯CT107D 单片机编程例题 -> 正文阅读

[嵌入式]蓝桥杯CT107D 单片机编程例题

一、按键

#include "stc15f2k60s2.h"
#define InitHC138(n) 	{P2 = P2 & 0x1f | (n << 5);}
sbit led1 = P0^0;
sbit S7 = P3^0;
sbit S6 = P3^1;
void Delay(unsigned int t)
{
	unsigned char i, j;
	while(t--)
	{
		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
}

void Init_Key()
{
	if(!S7)
	{
		Delay(15);		// 消抖
		if(!S7)
		{
			InitHC138(4);
			led1 = ~led1;
		}
		while(!S7);		// 松开检测
	}
	if(!S6)
	{
		Delay(15);
		if(!S6)
		{
			InitHC138(4);
			led1 = ~led1;
		}
		while(!S6);
	}
}

void main (void)
{
	InitHC138(5);
	P0 = 0x00;	P2 = 0x00;
	InitHC138(4);
	P0 = 0xff;	P2 = 0x00;
	while (1)
	{
		Init_Key();
	}
}

1、 按键感悟

有次意外看到有个例程不用消抖,而且还是很灵敏

#include "stc15f2k60s2.h"
#define InitHC138(n) 	{P2 = P2 & 0x1f | (n << 5);}
sbit S7 = P3^0;

void main()
{
	InitHC138(4);
	P0 = 0xff;	P2 = 0x00;
	InitHC138(5);
	P0 = 0x00;	P2 = 0x00;
	
	while(1)
	{
		if(S7 == 0)			// 不用消抖
		{
			InitHC138(4);
			P0 = 0xfe;
			P2 = 0x00;	// 锁住寄存器
			while(!S7);
		}
		else if(S7 == 1)
		{
			InitHC138(4);
			P0 = 0xff;
			P2 = 0x00;	// 锁住寄存器
		}
	}
}

二、外部中断

#include "stc15f2k60s2.h"
#define InitHC138(n) 	{P2 = P2 & 0x1f | (n << 5);}
sbit led1 = P0^0;
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S4 = P3^3;
void Delay_ms(unsigned int t)
{
	unsigned char i, j;
	while(t--)
	{
		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
}


void Init_key()
{
	if(!S7)
	{
		Delay_ms(15);
		if(!S7)
		{	
			S4 = 0;
		}
		while(!S7);
	}
	if(!S6)
	{
		Delay_ms(15);
		if(!S6)
		{	
			S4 = 1;
		}
		while(!S6);
	}
}
void Init_inter0()
{
	IT1 = 0;	// 低电平触发,触发之后必须是高电平变为低电平才会触发
//  IT1 = 1;	// 跳变沿触发	
	EX1 = 1;	// 打开 INT0 的中断允许
	EA  = 1;	// 打开总中断
}

void Servive_0()	interrupt 2		// 外部中断1
{
	InitHC138(4);
	led1 = ~led1;
}

void main (void)
{
	InitHC138(5);
	P0 = 0x00;	P2 = 0x00;
	InitHC138(4);
	P0 = 0xff;	P2 = 0x00;
	
	Init_inter0();
	while (1)
	{
		Init_key();
	}
}

定时器

#include "stc15f2k60s2.h"
#define InitHC138(n) 	{P2 = P2 & 0x1f | (n << 5);}
sbit led1 = P0^0;
sbit S7 = P3^0;
sbit S6 = P3^1;
sbit S4 = P3^3;


void Init_Timer_0()
{
	TMOD |= 0x01;	// 选择定时器0,工作方式1,仅用TR0打开启动
	
	TH0 = (65536 - 1000) / 256;		// 定时1ms
	TL0 = (65536 - 1000) % 256;
	
	ET0 = 1;		// 打开定时器0中断允许
	EA  = 1;		// 打开总中断
	TR0 = 1;		// 打开定时器
}

unsigned int count = 0;
void Timer0()	interrupt 1
{
	count++;
	if(count == 500)	// count == 500 既是经过500ms
	{
		count = 0;
		InitHC138(4);
		led1 = ~led1;
		P2 = 0x00;
	}
	// 一定要记得重载
	TH0 = (65536 - 1000) / 256;
	TL0 = (65536 - 1000) % 256;
}

  
void main (void)
{
	InitHC138(5);
	P0 = 0x00;	P2 = 0x00;
	InitHC138(4);
	P0 = 0xff;	P2 = 0x00;
	
	Init_Timer_0();
	while (1)
	{
		// CPU不参与定时器的运行
	}
}

四、串口通讯

#include "stc15f2k60s2.h"
#define InitHC138(n) 	{P2 = P2 & 0x1f | (n << 5);}
sbit led1 = P0^0;
void UartInit(void)		//115200bps@11.0592MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器1时钟为Fosc,即1T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0xE8;		//设定定时初值
	TH1 = 0xFF;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}

void uart() interrupt 4  //串口通信中断服务函数
{
	if(RI)
	{
		RI=0;
	}
	
	if(TI)
	{
		TI=0;
	}	
}

void uart_sendchar(unsigned char ch)	// 发送字符函数
{
	SBUF=ch;
	while(!TI);
	TI=0;
}

//void uart_sendstr(unsigned char *str)	// 发送字符串函数
//{
//	while(*str)
//		uart_sendchar(*str++);
//}

unsigned char uart_recechar()
{
	unsigned char dat;
	while(!RI);
	RI = 0;
	dat = SBUF;
	return dat;
}


void main (void)
{
	char i;
	InitHC138(5);
	P0 = 0x00;	P2 = 0x00;
	InitHC138(4);
	P0 = 0xff;	P2 = 0x00;
	
	UartInit();
	while (1)
	{
		i = uart_recechar();
		if(i == 'a')
		{
			InitHC138(4);	led1 = ~led1;	P2 = 0x00;
			uart_sendchar(i);
		}
	}
}

在串口通讯情况下重映射调用 printf( ) 函数

#include "STC15F2K60S2.H"
#include "stdio.h"

void Delay_ms(unsigned int t)
{
	unsigned char i, j;
	while(t--)
	{
		i = 12;
		j = 169;
		do
		{
			while (--j);
		} while (--i);
	}
}

void UartInit(void)        //9600bps@11.0592MHz
{
	SCON = 0x50;               
	AUXR |= 0x40;               
	AUXR &= 0xFE;               
	TMOD &= 0x0F;               
	TL1 = 0xE0;               
	TH1 = 0xFE;               
	ET1 = 0;               
	TR1 = 1;
	TI=1;               	//调用printf函数一定要令TI = 1 
}
void main()
{
	float i =3.14159;
	UartInit();
	while(1)
	{
		printf("hello world\r\n");
		printf("%.5f\n", i);
		Delay_ms(1000);
	}
}

在串口通信情况下用 sancf() 函数

#include "STC15F2K60S2.H"
#include "stdio.h"
#define InitHC138(n)	{P2 = P2 & 0x1f | (n << 5);}

void UartInit(void)                //9600bps@11.0592MHz
{
	SCON = 0x50;               
	AUXR |= 0x40;               
	AUXR &= 0xFE;               
	TMOD &= 0x0F;               
	TL1 = 0xE0;               
	TH1 = 0xFE;               
	ET1 = 0;               
	TR1 = 1; 
	TI  = 1;		// printf()
	RI  = 1;		// scanf()
}
void main()
{
	char i =0;
	
	InitHC138(5);
	P0 = 0x00; P2 = 0x00;
	InitHC138(4);
	P0 = 0xff; P2 = 0x00;
	
	UartInit();
	
	while(1)
	{
		scanf("%c", &i);
		printf("%c\n", i);
		if(i == 'a')
		{
			InitHC138(4);
			P00 = ~P00;
			P2 = 0x00;
		}
	}
}

五、DS18B20 温度测量

#include <stc15f2k60s2.h>
#include "onewire.h"	 // 官方底层驱动代码
unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf,0xc1,0x8e,0xc6,0x89,0x8c}; 
unsigned char buff[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};  
long  wendu;

long read18b20()
{
    unsigned char low,high;
    long temp;
    
    init_ds18b20();
    Write_DS18B20(0xcc);
    Write_DS18B20(0x44);
    Delay_OneWire(200);
    
    init_ds18b20();
    Write_DS18B20(0xcc);
    Write_DS18B20(0xbe);
    low=Read_DS18B20();
    high=Read_DS18B20();
    
//    temp=((high&0x0f)<<8)|(low);
//    temp*=6.25;
    
    temp=high&0x0f;
    temp=temp<<8;
    temp=temp|low;
    temp=temp*6.25;
    
    return temp;
    
}




void close()
{
    P2=(P2&0x1f)|0xa0;
    P0=0;
    P2&=0x1f;
    
    P2=(P2&0x1f)|0x80;
    P0=0xfb;
    P2&=0x1f; 
}
void delay(unsigned int ms)
{
    unsigned int i,j;
    for(i=ms;i>0;i--)
        for(j=845;j>0;j--);
}
void display()
{
    unsigned char index;
    for(index=0;index<8;index++)
    {
        P2=(P2&0x1f)|0xe0;
        P0=0xff;
        P2&=0x1f; 
        
        P2=(P2&0x1f)|0xc0;
        P0=1<<index;
        P2&=0x1f; 
        
        P2=(P2&0x1f)|0xe0;
        P0=buff[index];
        P2&=0x1f; 
        
        delay(1);
    }
    P2=(P2&0x1f)|0xe0;
    P0=0xff;
    P2&=0x1f; 
}
void main()
{
    close();
   
    while(1)
    {

       wendu=read18b20();
       buff[0]=tab[10];
       buff[1]=tab[10];
       buff[2]=tab[10];
       buff[3]=tab[10];
       buff[4]=tab[wendu/1000];
       buff[5]=tab[wendu%1000/100]&0x7f;
       buff[6]=tab[wendu%100/10];
       buff[7]=tab[wendu%10];
       display();     
        
    }
    
}

六、电子钟

#include "stc15f2k60s2.h"
#include "ds1302.h"		// 官方底层驱动代码
#define InitHC138(n)	{P2 = P2 & 0x1f | (n << 5);}
// 数码管
code unsigned char SMGNoDot_CA[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
code unsigned char SMGDot_CA[10] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

unsigned char Write_DS1302_adrr[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char Read_DS1302_adrr[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
// 21年3月3日, 周六, 23点59分24秒

unsigned char Timer[7] = {0x24,0x59,0x23,0x03,0x03,0x03,0x20};//BCD码    十六进制中的数字等效十进制的数字
//                        24秒 59分 23时  3号  3月 星期三  20年  
 

void DelaySMG(unsigned char t)
{
	while(t--);
}

void DisplaySMG_Bit(unsigned char pos, unsigned char dat)
{
	InitHC138(7);
	P0 = 0xff;	P2 = 0x00;
	InitHC138(6);
	P0 = 0x01 << pos;	P2 = 0x00;
	InitHC138(7);
	P0 = dat;	P2 = 0x00;
}


void DS1302_Config()  //读取当前时间
{
	char i;
	Write_Ds1302_Byte(0x8e,0x00); 	  //关闭保护,可以写入  
	for( i = 0; i < 7; i++)
	{
		Write_Ds1302_Byte(Write_DS1302_adrr[i],Timer[i] );
	}
	Write_Ds1302_Byte(0x8e,0x80);     //恢复保护,拒绝写入
}

void Read_DS1302_Timer()     //读取不用保护,写入需要保护
{
	char i;
	
	for(i = 0; i < 7; i++)
	{
		Timer[i] = Read_Ds1302_Byte( Read_DS1302_adrr[i] );
	}
}


void Display_DS1302()
{
	//时
	DisplaySMG_Bit(0, SMGNoDot_CA[Timer[2] / 16]);
	DelaySMG(100);
	DisplaySMG_Bit(1, SMGNoDot_CA[Timer[2] % 16]);
	DelaySMG(100);
	
	DisplaySMG_Bit(2,0xbf);
	DelaySMG(100);
	
	//分
	DisplaySMG_Bit(3, SMGNoDot_CA[Timer[1] / 16]);
	DelaySMG(100);
	DisplaySMG_Bit(4, SMGNoDot_CA[Timer[1] % 16]);
	DelaySMG(100);

	DisplaySMG_Bit(5,0xbf);
	DelaySMG(100);
	
	//秒
	DisplaySMG_Bit(6, SMGNoDot_CA[Timer[0] / 16]);
	DelaySMG(100);
	DisplaySMG_Bit(7, SMGNoDot_CA[Timer[0] % 16]);
	DelaySMG(100);


	// 关闭所有数码管
	InitHC138(6);
	P0 = 0xff;	P2 = 0x00;
	InitHC138(7);
	P0 = 0xff;	P2 = 0x00;
}

void main()
{
	InitHC138(4);
	P0 = 0xff;	P2 = 0x00;
	InitHC138(5);
	P0 = 0x00;	P2 = 0x00;
	
	DS1302_Config();
	while(1)
	{
		Read_DS1302_Timer();
		Display_DS1302();
	}
}

七、超声波

#include "stc15f2k60s2.h"
#include "intrins.h"
#define InitHC138(n)	{P2 = P2 & 0x1f | (n << 5);}
#define uint  unsigned int
#define uchar unsigned char
#define somenop	{_nop_();_nop_();_nop_();_nop_();_nop_();\
				 _nop_();_nop_();_nop_();_nop_();_nop_();}

sbit TX = P1^0;		// 发送引脚
sbit RX = P1^1;		// 接收引脚

code uchar tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
uchar dspbuf[8] = {10,10,10,10,10,10,10,10};
uchar dspcom = 0;

uint count = 0;
bit flag;
uint t = 0;

void Send_ult()
{
	uchar i = 8;	// 发送8个脉冲
	do
	{
		TX = 1;
		somenop;somenop;somenop;somenop;somenop;
		somenop;somenop;somenop;somenop;somenop;
		TX = 0;
		somenop;somenop;somenop;somenop;somenop;
		somenop;somenop;somenop;somenop;somenop;
	}while(i--);
}

// 显示函数
void Display()
{
	InitHC138(7);
	P0 = 0xff;					P2 = 0x00;
	InitHC138(6);
	P0 = (1 << dspcom);			P2 = 0x00;
	InitHC138(7);
	P0 = tab[dspbuf[dspcom]];	P2 = 0x00;
	
	if(++dspcom == 8)
	{
		dspcom = 0;
	}
}

uint distance = 0;
void Init_time()
{
	TMOD |= 0x11;	// 配置定时器工作模式
	TH0 = (65536 - 2000) / 256;    // 定时2毫秒
	TL0 = (65536 - 2000) % 256;
	TH1 = 0;	// 计数		
	TL1 = 0;
	
	EA  = 1;	// 打开总开关
	ET0 = 1;	// 打开定时器0中断
	TR0 = 1;	// 启动定时器0
}

void Servie_time()	interrupt 1		// 定时器0中断
{
	TH0 = (65536 - 2000) / 256;
	TL0 = (65536 - 2000) % 256;
	Display();	// 每2毫秒数码管刷新一次
	if(++count == 200)	// 400 毫秒发送一次
	{
		flag = 1;
		count = 0;
	}
}

void Config_ult()
{
	// 200 毫秒刷新一次
	if(flag)
	{
		flag = 0;
		Send_ult();		// 发送方波信号
		TR1 = 1;		// 开始计时
		while((RX == 1) && (TF1 == 0));		// 等待收到脉冲
		TR1 = 0;		// 结束计时
		
		// 如果发生溢出
		if(TF1 == 1)
		{
			TF1 = 0;
			distance = 9999;	// 无返回
		}
		else
		{
			// 计算时间
			t = TH1;	// 获取收到脉冲的时间
			t <<= 8;
			t |= TL1;
			distance = (uint)(t*0.017);		// 计算距离
		}
		TH1 = 0;	// 重新从零开始计时
		TL1 = 0;
	}
	
	// 数据处理
	dspbuf[5] = distance / 100;
	dspbuf[6] = distance % 100 / 10;
	dspbuf[7] = distance % 10;
}

void main()
{
	InitHC138(4);
	P0 = 0xff;	P2 = 0x00;
	InitHC138(5);
	P0 = 0x00;  P2 = 0x00;
	
	Init_time();
	while(1)
	{
		Config_ult();
	}
}	

八、EEPROM 存储器

// main.c
#include "stc15f2k60s2.h"
#include "iic.h"		// 官方提供的底层驱动
#include "intrins.h"
#define InitHC138(n)	{P2 = P2 & 0x1f | (n << 5);}
#define uchar unsigned char
#define uint unsigned int

code uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//定义段码数组
uchar boot_time = 0;	// 存放开机次数

void Delay_ms(uint t)		//@11.0592MHz
{
	unsigned char i, j;
	while(t--)
	{
		_nop_();
		_nop_();
		_nop_();
		i = 11;
		j = 190;
		do
		{
			while (--j);
		} while (--i);		
	}
}

// *******************自添加部分***************************

void write_eeprom(unsigned char add,unsigned char date)
{
	IIC_Start();//启动总线
	IIC_SendByte(0xa0);//发送设备地址,第八位为0所以为写
	IIC_WaitAck();//等待应答
	IIC_SendByte(add);//发送数据地址
	IIC_WaitAck();//等待应答
	IIC_SendByte(date);//发送数据
	IIC_WaitAck();//等待应答
	IIC_Stop();//停止总线
}

unsigned char read_eeprom(unsigned char add)
{
	unsigned char temp;//定义变量temp用来获得eeprom中的数据
	EA = 0;//关闭中断,中断可能会影响总线时序
	IIC_Start();//开启总线
	IIC_SendByte(0xa0);
	//发送设备地址,第八位为0所以为写,因为读取的时候为读取现在的地址加一,所以要发送现在写的地址进去
	IIC_WaitAck();//等待应答
	IIC_SendByte(add);//发送数据地址
	IIC_WaitAck();//等待应答

	IIC_Start();//开启总线
	IIC_SendByte(0xa1);//发送设备地址,第八位为1所以为读,读取的地址为刚刚我们写入的地址
	IIC_WaitAck();//等待应答
	temp = IIC_RecByte();//读取数据
	IIC_WaitAck();//等待应答
	IIC_Stop();//停止总线
	EA = 1;//打开中断
	return temp;//返回temp
}

//************************************************************

void Display_SMG(uint pos, uint dat)
{
	InitHC138(7);
	P0 = 0xff;			P2 = 0x00;
	InitHC138(6);
	P0 = 0x01 << pos;	P2 = 0x00;
	InitHC138(7);
	P0 = dat;			P2 = 0x00;
}

void Show_SMG()
{
	Display_SMG(6, tab[boot_time / 10]);
	Delay_ms(10);
	Display_SMG(7, tab[boot_time % 10]);
	Delay_ms(10);
}

void main()
{
	InitHC138(4);
	P2 = 0xff;	P2 = 0x00;
	InitHC138(5);
	P2 = 0x00;	P2 = 0x00;
	
	boot_time = read_eeprom(0x01);
	write_eeprom(0x01,++boot_time);
	while(1)
	{
		Show_SMG();
	}
}

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-11-17 12:54:59  更:2021-11-17 12:56:14 
 
开发: 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 8:27:19-

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