第 14 回蘭橋杯 MCU 省大会のシミュレーション プログラムの質問に対する参考回答

目次

トピック

 トピック分析

 シリアルポートの初期化設定

 ソースコード

main.h

main.c

初期化

Init.c

SMG.h

SMG.c

DSQ.h

DSQ.c

ヤンシー・h

YanShi.c

JZKey.h

JZKey.c

CSB.h

CSB.c

ChuanKou.h

ChuanKou.c

トピック

 

 トピック分析

        この一連の模擬質問は、非常にまれにテストされる周辺機器であるシリアル ポートをテストします。ただし、シリアル ポート モジュールのコードは難しいものではなく、インターネット上で参照でき、シリアル ポートの初期化はstc-isp 書き込みソフトウェアを使用して構成することもできます。

 シリアルポートの初期化設定

 シリアル ポートの初期化コードは簡単に入手できます。

 ソースコード

main.h

#ifndef __MAIN_H_
#define __MAIN_H_

#define uchar unsigned char
#define uint unsigned int

#include <STC15F2K60S2.H>
#include <string.h>
#include <stdio.h>

#include "Init.h"
#include "SMG.h"
#include "DSQ.h"
#include "YanShi.h"
#include "JZKey.h"
#include "CSB.h"
#include "ChuanKou.h"

void LED_Show();

#endif

main.c

#include "main.h"

uchar key_num=0;
uchar key_num_old=0;
uchar JieMian=0;//界面。0:距离显示界面;1:参数显示界面
int JuLi_CanShu=30;//距离参数
uint ju_li=0;//距离
uchar date[50];
uchar L3_flag=0;
uint L3_time=0;
uchar ji_li_time=0;

void main(){
	Init_BZ();
	SMG_Init();
	ChuanKou_Init();
	DSQ_2_Init();
	JZKey_Init();
	while(1){
		key_num_old=key_num;
		key_num=JZKEy_GetKeynum();
		if(key_num_old!=key_num){
			if(key_num==4){
				JieMian++;
				JieMian=JieMian%2;
			}
			else if(key_num==8&&JieMian==0){
				JuLi_CanShu=ju_li;
			}
			else if(key_num==12&&JieMian==1){
				JuLi_CanShu=JuLi_CanShu+10;
				if(JuLi_CanShu>=999){
					JuLi_CanShu=999;
				}
			}
			else if(key_num==16&&JieMian==1){
				JuLi_CanShu=JuLi_CanShu-10;
				if(JuLi_CanShu<=0){
					JuLi_CanShu=0;
				}
			}
			else if(key_num==9){
				sprintf(date,"Distance;%dcm\n",ju_li);
				SendString(&date);
				memset(&date,'\0',sizeof(date));
			}
		}
		
		if(ji_li_time>=50){
			ju_li=CSB_GetJuLi();
			ji_li_time=0;
		}
	}
}

void DSQ_2_ZD() interrupt 12{
	ji_li_time++;
	if(JieMian){
		if(JuLi_CanShu>=100){
			SMG_Show(25,2,16,16,16,JuLi_CanShu/100,(JuLi_CanShu/10)%10,JuLi_CanShu%10);
		}
		else if(JuLi_CanShu>=10){
			SMG_Show(25,2,16,16,16,16,JuLi_CanShu/10,JuLi_CanShu%10);
		}
		else if(JuLi_CanShu>=0){
			SMG_Show(25,2,16,16,16,16,16,JuLi_CanShu);
		}
	}
	else{
		if(ju_li>=100){
			SMG_Show(25,1,16,16,16,ju_li/100,(ju_li/10)%10,ju_li%10);
		}
		else if(ju_li>=10){
			SMG_Show(25,1,16,16,16,16,ju_li/10,ju_li%10);
		}
		else if(ju_li>=0){
			SMG_Show(25,1,16,16,16,16,16,ju_li);
		}
	}
	
	if(ju_li>JuLi_CanShu){
		L3_time++;
		L3_flag=1;
		if(L3_time>=400){
			L3_time=0;
		}
	}
	else{
		L3_time=0;
		L3_flag=0;
	}
	
	LED_Show();
}

void LED_Show(){
	uchar L1_2=0xff;
	uchar L3=0xff;
	if(JieMian){	
		L1_2=0xfd;
	}
	else{
		L1_2=0xfe;
	}
	if(L3_flag){
		if(L3_time<200){
			L3=0xfb;
		}
	}
	P0=L1_2&L3;
	P2=(P2&0x1f)|0x80;
	P2=(P2&0x1f)|0x00;
}

初期化

#ifndef __INIT_H_
#define __INIT_H_

#include <STC15F2K60S2.H>

void Init_BZ();

#endif

Init.c

#include "Init.h"

void Init_BZ(){
	P2=(P2&0x1f)|0xa0;
	P0=0x00;
	P2=(P2&0x1f)|0x80;
	P0=0xff;
}

SMG.h

#ifndef __SMG_H_
#define __SMG_H_

#include <STC15F2K60S2.H>

void SMG_Init();
void SMG_Show(unsigned char n1,n2,n3,n4,n5,n6,n7,n8);

#endif

SMG.c

#include "SMG.h"

unsigned char code t_display[]={                       //????
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

void SMG_Init(){
	P2=(P2&0x1f)|0xc0;
	P0=0xff;
	P2=(P2&0x1f)|0xe0;
	P0=0xff;
}

void SMG_Show(unsigned char n1,n2,n3,n4,n5,n6,n7,n8){
	static unsigned char i=0;
	i++;
	i=i%8;
	P2=(P2&0x1f)|0xc0;
	switch(i){
		case 1:{
			P0=0x01;
			P2=(P2&0x1f)|0xe0;
			P0=~t_display[n1];
			break;
		}
		case 2:{
			P0=0x02;
			P2=(P2&0x1f)|0xe0;
			P0=~t_display[n2];
			break;
		}
		case 3:{
			P0=0x04;
			P2=(P2&0x1f)|0xe0;
			P0=~t_display[n3];
			break;
		}
		case 4:{
			P0=0x08;
			P2=(P2&0x1f)|0xe0;
			P0=~t_display[n4];
			break;
		}
		case 5:{
			P0=0x10;
			P2=(P2&0x1f)|0xe0;
			P0=~t_display[n5];
			break;
		}
		case 6:{
			P0=0x20;
			P2=(P2&0x1f)|0xe0;
			P0=~t_display[n6];
			break;
		}
		case 7:{
			P0=0x40;
			P2=(P2&0x1f)|0xe0;
			P0=~t_display[n7];
			break;
		}
		case 0:{
			P0=0x80;
			P2=(P2&0x1f)|0xe0;
			P0=~t_display[n8];
			break;
		}
	}
	P2=(P2&0x1f)|0x00;
}

DSQ.h

#ifndef __DSQ_H_
#define __DSQ_H_

#include <STC15F2K60S2.H>

void DSQ_2_Init();

#endif

DSQ.c

#include "DSQ.h"

void DSQ_2_Init(){
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0x20;		//设置定时初值
	T2H = 0xD1;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	AUXR=AUXR&0xf7;
	IE2=IE2|0x04;
	EA=1;
}

ヤンシー・h

#ifndef __YANSHI_H_
#define __YANSHI_H_

#include <STC15F2K60S2.H>
#include "intrins.h"

void Delay10ms();

#endif

YanShi.c

#include "YanShi.h"

void Delay10ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 117;
	j = 184;
	do
	{
		while (--j);
	} while (--i);
}

JZKey.h

#ifndef __JZKEY_H_
#define __JZKEY_H_

#include "YanShi.h"

void JZKey_Init();
unsigned char JZKEy_GetKeynum();

#endif

JZKey.c

#include "JZKey.h"

void JZKey_Init(){
	P32=1;
	P33=1;
	P34=0;
	P35=0;
	P42=0;
	P44=0;
}

unsigned char JZKEy_GetKeynum(){
	unsigned char key_num=0;
	if(P32==0){
		P32=0;
		P42=1;
		if(P42==0){
			Delay10ms();
			if(P42==0){
				key_num=9;
			}
			//while(P42==0);
		}
	}
	else if(P33==0){
		P33=0;
		P34=1;
		P35=1;
		P42=1;
		P44=1;
		if(P34==0){
			Delay10ms();
			if(P34==0){
				key_num=16;
			}
			//while(P34==0);
		}
		else if(P35==0){
			Delay10ms();
			if(P35==0){
				key_num=12;
			}
			//while(P35==0);
		}
		else if(P42==0){
			Delay10ms();
			if(P42==0){
				key_num=8;
			}
			//while(P42==0);
		}
		else if(P44==0){
			Delay10ms();
			if(P44==0){
				key_num=4;
			}
			//while(P44==0);
		}
	}
	JZKey_Init();
	return key_num;
}

CSB.h

#ifndef __CSB_H_
#define __CSB_H_

#include <STC15F2K60S2.H>
#include "intrins.h"

#define FS P10
#define JS P11

void Delay13us();
void CSB_FS_MC();
float CSB_GetJuLi();

#endif

CSB.c

#include "CSB.h"

void Delay13us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 36;
	while (--i);
}

void CSB_FS_MC(){
	unsigned char i;
	for(i=0;i<8;i++){
		FS=1;
		Delay13us();
		FS=0;
		Delay13us();
	}
}

float CSB_GetJuLi(){
	float ju_li;
	unsigned int time=0;
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0=0;
	TH0=0;
	ET0=0;
	TF0=0;
	
	CSB_FS_MC();
	TR0=1;
	while(JS==1&&TF0==0);
	TR0=0;
	if(JS==0&&TF0==0){
		time=((unsigned int)TH0<<8)|(unsigned int)TL0;
		ju_li=(time*1.0*0.017)/12.0;
	}
	else{
		ju_li=999.0;
		TF0=0;
	}
	TH0=0;
	TL0=0;
	return ju_li;
}

ChuanKou.h

#ifndef __CHUANKOU_H_
#define __CHUANKOU_H_

#include <STC15F2K60S2.H>

void ChuanKou_Init();
void SendData(unsigned char date);
void SendString(char *s);

#endif

ChuanKou.c

#include "ChuanKou.h"

void ChuanKou_Init(){
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器1时钟为Fosc,即1T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0xC7;		//设定定时初值
	TH1 = 0xFE;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	ES=0;
	EA=1;
}

void SendData(unsigned char date){
	SBUF=date;
	while(TI==0);
	TI=0;
}

void SendString(unsigned char *s){
	while (*s!='\0'){//检测字符串结束标志
		SendData(*s++);//发送当前字符
	}
}

おすすめ

転載: blog.csdn.net/CETET/article/details/129974676