(萌新一枚,連肝4個小時,在這里分享給大家,)
這一屆的題目總體來說,難度不大,但第一次也是唯一一次考到了矩陣鍵盤,足以引起我們的注意,我在寫代碼的程序,主要遇到的障礙就是矩陣鍵盤的使用過于粗糙,希望矩陣鍵盤沒有怎么練習過的,只會運用最基礎的操作的小伙伴能進一步加強這一塊的學習,防止比賽暴雷,,,,
如果你發現了程式需要優化的地方,請一定要告訴我!


onewire.c
/*
程式設計:單總線驅動程式
軟體環境:Keil uVision 4.10
硬體環境:CT107單片機綜合實訓平臺(外部晶振12MHz)IAP15F2K61S2
日期:2011-8-9
*/
#include "reg52.h"
#include "onewire.h"
sbit DQ = P1^4; //單總線介面
//單總線延時函式
void Delay_OneWire(unsigned int t) //STC89C52RC
{
t *= 10;//時間擴大十倍
while(t--);
}
//通過單總線xiangDS18B20寫一個位元組
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//從DS18B20讀取一個位元組
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//DS18B20設備初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
uchar read_temperatuer(void)
{
uchar LSB, MSB;
uchar temp;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay_OneWire(100);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB = Read_DS18B20();
MSB = Read_DS18B20();
init_ds18b20();
temp = (MSB << 8)|LSB;
temp >>= 4;//右移4位,只取整數部分
return temp;
}
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#define uchar unsigned char
#define uint unsigned int
extern uchar read_temperatuer(void);
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
#endif
main.c
#include <REGX52.H>
#include <onewire.h>
sfr P4 = 0xc0;
sbit P42 = P4^2;
sbit P44 = P4^4;
sbit L1 = P0^0;
sbit L2 = P0^1;
void Delay(uint t);
void Init_hc573(uint s);
void key_scan(void);
void inputdat(uint key);//輸入資料
void save_t(void);//保存輸入的資料
void Init_Timer0(void);
void DisplaySMG_Dat(uint pos, uint dat);
void DisplaySMG_all(void);//清空所有數碼管
void DisplaySMG(void);
uint code Shu[] =
{0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,0x80,0x90,//0-9
0xbf, 0xff};//-和滅
uint yi=11,er=11,san=11,si=11, wu=11, liu=11, qi=11, ba=11;
uint temperature;//溫度
uint set;//控制顯示界面標志位
uint set_t1, set_t2, set_t3, set_t4;//設定溫度的臨時資料
uint Tmax = 30, Tmin = 20;
uint level;//溫度等級
uint sel;//選擇要修改的資料
uint flag;//計算設定按鍵按下的次數
uint clear;//清空資料標志位
uint count_0;//定時器時間控制
uint count_1;
uint count_2;
void main(){
Init_hc573(4);
P0 = 0xff;
Init_hc573(5);
P0 = 0x00;
Init_Timer0();
while(1){
key_scan();
if(temperature < Tmin){
level = 0;
Init_hc573(5);
P0 = 0x00;
}
else if((temperature >= Tmin)&&(temperature <= Tmax)){
level = 1;
Init_hc573(5);
P0 = 0x00;
}
else
{
level = 2;
Init_hc573(5);
P0 = 0x10;
}
if(set== 0){
EA = 1;
ET0 = 1;
temperature = read_temperatuer();
yi = 10;er = level;san = 10;
si = 11;wu = 11;liu = 11;
qi = temperature/10;ba = temperature%10;
}
else{
//關閉定時器并清空資料
EA = 0;
ET0 = 0;
count_0 = 0;
count_1 = 0;
count_2 = 0;
yi = 10;er = set_t1;san = set_t2;
si = 11;wu = 11;liu = 10;
qi = set_t3;ba = set_t4;
}
DisplaySMG();
}
}
void Delay(uint t){
while(t --);
}
void Init_hc573(uint s){
switch(s){
case 4:P2 = (P2 &0x1f)|0x80;break;//LED
case 5:P2 = (P2 &0x1f)|0xa0;break;//蜂鳴器和繼電器
case 6:P2 = (P2 &0x1f)|0xc0;break;//數碼管com埠
case 7:P2 = (P2 &0x1f)|0xe0;break;//段碼
}
}
static uint key;
void key_scan(void){
uint temp;
P3 = 0x7f;P42 = 1;P44 = 0;//掃描第一列
temp = P3;
temp &= 0x0f;//判斷第四位是否發生變化 0111 1111&0000 1111 = 0000 1111
if(temp != 0x0f){
Delay(200);
if(temp != 0x0f){
temp = P3;
switch(temp)//便于直接控制到每個按鍵
{
case 0x7e:if(set == 1){sel ++;key = 0;inputdat();}break;
case 0x7d:if(set == 1){sel ++;key = 3;inputdat();}break;
case 0x7b:if(set == 1){sel ++;key = 6;inputdat();}break;
case 0x77:if(set == 1){sel ++;key = 9;inputdat();}break;
}
while(temp != 0x0f){//重新判斷,否則temp永遠不能等于0x0f
temp = P3;
temp &= 0x0f;//若松開,則temp = 0x0f;
}
}
}
P3 = 0xbf;P42 = 0;P44 = 1;//判斷第二列
temp = P3;
temp &= 0x0f;//判斷第四位是否發生變化
if(temp != 0x0f){
Delay(200);
if(temp != 0x0f){
temp = P3;
switch(temp)
{
case 0xbe:if(set == 1){sel ++;key = 1;inputdat();}break;
case 0xbd:if(set == 1){sel ++;key = 4;inputdat();}break;
case 0xbb:if(set == 1){sel ++;key = 7;inputdat();}break;
case 0xb7:set = 1;flag ++;if(flag == 2){save_t();}break;
}
while(temp != 0x0f){
temp = P3;
temp &= 0x0f;
}
}
}
P3 = 0xdf;P42 = 1;P44 = 1;//掃描第三列
temp = P3;
temp &= 0x0f;
if(temp != 0x0f){
Delay(200);
if(temp != 0x0f){
temp = P3;
switch(temp)
{
case 0xde:if(set == 1){sel ++;key = 2;inputdat();}break;
case 0xdd:if(set == 1){sel ++;key = 5;inputdat();}break;
case 0xdb:if(set == 1){sel ++;key = 8;inputdat();}break;
case 0xd7:if(set == 1){sel ++;clear = 1;inputdat();}break;
}
while(temp != 0x0f){
temp = P3;
temp &= 0x0f;
}
}
}
}
void inputdat(void){
if(clear == 0){
switch(sel){
case 1:set_t1 = key;break;
case 2:set_t2 = key;break;
case 3:set_t3 = key;break;
case 4:set_t4 = key;break;
}
}
else{//清空資料
set_t1 = 0;
set_t2 = 0;
set_t3 = 0;
set_t4 = 0;
sel = 0;//重新輸入
clear = 0;
}
}
void save_t(void){
if((set_t1*10+ set_t2) > (set_t3*10+ set_t4)){
Tmin = set_t3*10+ set_t4;
Tmax = set_t1*10+ set_t2;
sel = 0;
set = 0;
Init_hc573(4);
L2 = 1;
}
else{//輸入錯誤,重新輸入
set_t1 = 0;
set_t2 = 0;
set_t3 = 0;
set_t4 = 0;
sel = 0;
set = 1;
Init_hc573(4);
L2 = 0;
}
flag = 0;//清空設定按鍵標志位
}
void Init_Timer0(void){//@12MHz
TMOD = 0x01;
TH0 = (65535 -20000)/256;
TL0 = (65535- 20000)%256;
// EA = 1;
// ET0 = 1;
TR0 = 1;
}
void service_Timer0(void) interrupt 1{
TH0 = (65535 -20000)/256;
TL0 = (65535- 20000)%256;
count_0 ++;
count_1 ++;
count_2 ++;
if(count_0 == 4){
count_0 = 0;
if(level == 0){
if(L1 == 0){
Init_hc573(4);
P0 = 0xff;//避免其他LED閃爍
L1 = 1;
}
else
{
Init_hc573(4);
P0 = 0xff;
L1 = 0;
}
}
}
if(count_1 == 2){
count_1 = 0;
if(level == 1){
if(L1 == 0){
Init_hc573(4);
P0 = 0xff;
L1 = 1;
}
else{
Init_hc573(4);
P0 = 0xff;
L1 = 0;
}
}
}
if(count_2 == 1){
count_2 = 0;
if(level == 2){
if(L1 == 0){
Init_hc573(4);
P0 = 0xff;
L1 = 1;
}
else{
Init_hc573(4);
P0 = 0xff;
L1 = 0;
}
}
}
}
void DisplaySMG_Dat(uint pos, uint dat){
Init_hc573(6);
P0 = 0x01 << pos;
Init_hc573(7);
P0 = dat;
Delay(50);
P0 = 0xff;
}
void DisplaySMG_all(void){
Init_hc573(6);
P0 = 0xff;
Init_hc573(7);
P0 = 0xff;
}
void DisplaySMG(void){
DisplaySMG_Dat(0, Shu[yi]);
Delay(100);
DisplaySMG_Dat(1, Shu[er]);
Delay(100);
DisplaySMG_Dat(2, Shu[san]);
Delay(100);
DisplaySMG_Dat(3, Shu[si]);
Delay(100);
DisplaySMG_Dat(4, Shu[wu]);
Delay(100);
DisplaySMG_Dat(5, Shu[liu]);
Delay(100);
DisplaySMG_Dat(6, Shu[qi]);
Delay(100);
DisplaySMG_Dat(7, Shu[ba]);
Delay(100);
DisplaySMG_all();
}
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/267114.html
標籤:其他
下一篇:計算機網路基礎之物理層功能與協議
