欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
C51單片機設定位閃爍關閉不掉 附程序
[打印本頁]
作者:
宏達工控
時間:
2023-8-9 17:07
標題:
C51單片機設定位閃爍關閉不掉 附程序
#include<reg51.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define AT24C02_ADDRESS 0xA0 //0xA0 1010 00000寫地址
uint Count;
uint Set_Count;
uint Num_L;
uint Num_H;
uint num1;
char num2=0;
sbit I2C_SCL= P1^6;
sbit I2C_SDA= P1^7;
sbit Start_Dianji=P3^0; //電機啟動_dianji
sbit forward=P3^1; //正轉檢測
//sbit back=P3^1; //反轉檢測
sbit run=P3^7; //運行信號
sbit jia_up=P1^0;// 增加鍵
sbit jian_down=P1^1;//減少鍵
sbit yiwei_up=P1^2; //移位鍵
sbit qingling=P1^3; //清零鍵
uchar code ledcode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //共陰數碼管編碼0-9 modtable={ {0,0,0,0},{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1} ,{1,1,1,1} }
uchar data Ledbuff[]={0, 0, 0, 0, 0, 0, 0, 0};//顯示緩沖區
unsigned char n = 0, n_50ms; //添加閃爍.n=數碼管移動位數
bit flag; //添加閃爍
#define I2CDelay_us(){_nop_();_nop_();_nop_();_nop_();}//voidI2CDelay_us
/***********************
AT24C初始化I2C_init
*************************/
void I2C_init()
{
I2C_SCL=1;
I2C_SDA=1;//首先確保SCL SDA都是高電平
}
/***********************
產生總線起始信號I2C_Start
*************************/
void I2C_Start(void )
{
I2C_SDA=1;//首先確保SCL SDA都是高電平
I2C_SCL=1; //確保SCL高電平
I2C_SDA=0;//先在SCL為高時拉低SDA,即為起始信號
I2C_SCL=0; //在拉低 SCL,鉗住I2C總線準備發送或接收數據
}
/***********************
產生總線停止信號:先拉低SDA在拉低SCL
*************************/
void I2C_Stop(void )
{
I2C_SDA=0;//首先確保SCL SDA都是低電平
I2C_SCL=1; //先拉高 SCL
I2C_SDA=1;//在拉高 SDA
}
/*******************************************************************************
*@brief I2C發送一個字節數據
*@param Byte要發送的字節
*@retval 無
起始信號后必須送一個從機地址(7)位,1-7位為要接收器件的地址,第八位讀寫位0發送1接收,第9位ACK應答位,
緊接著為第一個數據字節,然后一位應答位ACK后面繼續第二個數據字節
**********************************************************************************/
void I2C_SendByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
I2C_SDA=Byte&(0x80>>i); //1000 0000右移 i個位
I2C_SCL=1; //先拉高 SCL
I2C_SCL=0; //SCL
}
}
/***********************************************************************************************
*@brief I2C讀取 接收一個字節
*@param 無
*@retval 讀取 接收到的一個字節數據
********************************************************************************************/
unsigned char I2C_ReceiveByte(void)
{
unsigned char i,Byte=0x00;//
I2C_SDA=1; //
for(i=0;i<8;i++)
{
I2C_SCL=1; //先拉高 SCL
if(I2C_SDA){Byte |= (0x80>>i); }
I2C_SCL=0; //SCL
}
return Byte;
}
/*********************
*@brief I2C發送應答Ack
*@param AckBit應答位 0為應答(成功) 1為非應答(失敗)
*@retval 無
************************/
void I2C_SendAck(unsigned char AckBit)
{
I2C_SDA=AckBit;
I2C_SCL=1; //先拉高 SCL
I2C_SCL=0; //SCL
}
/*********************
*@brief I2C接收應答位
*@param 無
*@retval AckBit應答位 0為應答(成功) 1為非應答(失。
************************/
unsigned char I2C_ReceiveAck(void)
{
unsigned char AckBit;
I2C_SDA=1;
I2C_SCL=1; //先拉高 SCL
AckBit=I2C_SDA;
I2C_SCL=0; //SCL
I2C_SDA=1;//少此行錯誤不能讀取
return AckBit; //返回值
}
/**********向AT24C寫數據***********
*@brief AT24C寫入一個字節
*@param WordAddress要寫入字節的地址
*@param Data要寫入的數據
*@retval無
寫多字節時,寫入一個字節。在寫一個字節前,必須延時5ms
************************/
void AT24C_WriteByte(unsigned char WordAddress,Data)
{
I2C_Start();//啟動總線
I2C_SendByte(AT24C02_ADDRESS);//發送寫操作地址+寫數據(0xa0)
I2C_ReceiveAck(); //等待應答
I2C_SendByte(WordAddress);//要寫入的地址
I2C_ReceiveAck(); //等待應答完成
I2C_SendByte(Data); //要寫入的數據,第一字節 ,第二字節注意:每個字節都回應一個應答位0,如果沒有回應說明寫入不成功
I2C_ReceiveAck(); //等待完成 注意:每個字節都回應一個應答位0,如果沒有回應說明寫入不成功
I2C_Stop(); //發送結束信號:停止總線
}
/************從AT24C中讀出數據*********
*@brief AT24C讀取一個字節
*@param WordAddress要讀出字節的地址
*@param 無
*@retval要讀出的數據
************************/
unsigned char AT24C_ReadByte(unsigned char WordAddress) //void
{
unsigned char Data;
I2C_Start(); //發送起始信號:啟動總線
I2C_SendByte(AT24C02_ADDRESS); //接上首字節,發送器件寫操作地址+寫數據(0xa0)這里寫操作時維綸把所要讀的數據地址AT24C02_ADDRESS通知讀取哪個地址信息
I2C_ReceiveAck(); //等待完成應答
I2C_SendByte(WordAddress);//發送要讀取內存的地址(WORD ADDRESS)
I2C_ReceiveAck(); //等待應答完成
I2C_Start();//在次啟動總線
I2C_SendByte(AT24C02_ADDRESS| 0x01); //對E2PROM進行讀操作(0XA1)E2PROM會自動向主機發回數據,讀取一個字節后回應一個應答位,后會繼續傳送下一個地址的數據0xa1
I2C_ReceiveAck(); //等待完成
Data= I2C_ReceiveByte(); //要讀出的數據到Data
I2C_SendAck(1); //等待完成::如果不想讀了,就發送一個非應答位NAK(1),發送結束,停止總線
I2C_Stop(); //停止總線
return Data ;//返回值
}
/************延時函數***********************/
void delay_ms(uint ms)
{
uchar k;
while(ms--)
{
for(k = 0; k < 120; k++);
}
}
///////////////////////////////////////////////////////////////
void display() //顯示程序display(uchar a,b,c,d,e)
{
unsigned char i,w = 1;//添加閃爍 i, w = 128
/********************************/
switch(i)//使用多分支選擇語句 i=count display 0x代表16進制
{
case(0):Ledbuff[7]=Set_Count/1000;break; //取設定千位字符送緩存
case(1):Ledbuff[6]=Set_Count/100%10;break; //取設定百位字符送緩沖
case(2):Ledbuff[5]=Set_Count/10%10;break; //取設定十位字符送緩沖
case(3):Ledbuff[4]=Set_Count%10;break; //取設定個位字符送緩存
case(4):Ledbuff[3]=Count/1000;break; //取計數千位字符送緩存
case(5):Ledbuff[2]=Count/100%10;break;
case(6):Ledbuff[1]=Count/10%10;break;
case(7):Ledbuff[0]=Count%10;break;
}
P0=0x00; //消陰:段碼全部低電平關閉
//添加閃爍: 閃爍字符 0,N閃爍位置 Ledbuff[n] = 10; Ledbuff[ n ] = i Ledbuff[ n+3 ] 是從第四個字符開始閃爍
if (flag) Ledbuff[ n+3 ] = 245 ; //共陰字碼表取反10 ,共陽=10 因為n是從1開始,所以第一個閃爍的是Ledbuff[4] ~10=(0000 1010)
/**********************************/
P2=~(0x01<<i); //P2位選,左移i位取反
P0=ledcode[Ledbuff[i]]; //P0字符刷新顯示
delay_ms(1); //顯示2MS
i=++i%8; //自加1
}
void Adjust() //按鍵設定匝數,用P2.4個位-P2.7(千位)前四位數碼管顯示void
{
// **********原程序************************
if(yiwei_up==0) //移位按鍵按下
{
//********這里開啟定時中斷,進入閃爍計時**************************
while(!yiwei_up); //等待移位按鍵松開
{
n ++; if(n>4) n=1; //移位:左移一位 ,移到千位后,在按返回個位
}
ET0=1; //開啟T0
TR0 = 1; // 啟動T0 工作開始 選擇的數碼管開始閃爍
}
//加減按鍵檢測
if(Set_Count>=0 && Set_Count<9999)//最大9999yiwei_Count=0; //設定加 jia_up==0
{
if (jia_up==0) //增加按鍵按下
{
while(!jia_up);//等待加按鍵松開
num1=Set_Count ;
{
if (n == 1 ) //
{
Set_Count += 1; //設定+1
}
if ( n == 2 &&Set_Count<9990)
{
Set_Count += 10; //設定+10
}
if ( n == 3 && Set_Count<9900 )
{
Set_Count += 100; //設定+100
}
if ( n == 4 && Set_Count<9000 )
{
Set_Count += 1000; //設定+1000
}
}
}
if (jian_down==0) //減少按鍵按下
{
while(!jian_down);//等待按鍵松開
num1=Set_Count ;
{
if ( n ==1 && Set_Count>1 ) // 移位在個位
{
Set_Count -= 1; //設定-1
}
if ( n == 2 && Set_Count>9)
{
Set_Count -= 10; //設定+1
}
if (n == 3 && Set_Count>99 )
{
Set_Count -= 100; //設定-100
}
if ( n == 4 && Set_Count>999 )
{
Set_Count -= 1000; //設定+1
}
}
}
if ( num1 != Set_Count ) // 設定值有變化,存入24c
{
//寫入數據
AT24C_WriteByte(0,Set_Count%256);
delay_ms(5) ; //顯示2MS
AT24C_WriteByte(1,Set_Count/256);
delay_ms(5); //顯示2MS
}
}
if( num2==3) //設定超時保存后,閃爍幾次關閉閃爍
{ET0=1;TR0 = 0; num2=0 ;} //num2++ ;
num1=Set_Count ; //保存完成 將設定值送到設定值變化緩存
}
/**********************************************************
主函數 ET=1 // 是打開定時器0中斷允許,EA = 1; // 是打開總中斷允許
**********************************************************/
void main()
{
/*****************Y添加閃爍中斷初始化**********************/
TMOD = 0x01; //是配置定時器0為16位定時模式
TH0 = 0x3C; // 設定高位初值
TL0 = 0xB0; // 設定低位初值
EA=1 ; //開啟總中斷
// IE = 0x82; //中斷允許寄存器0x82=10000010開了總中斷 ,相當于EA=1打開總中斷 ;ET0=1;打開T0
/*********************************************************************/
I2C_init(); //初始化24C02
//讀取低八位從24C-02的0x00讀取到Num_L,高八位從0x01讀取到Num_H
Num_L = AT24C_ReadByte(0);
Num_H |=AT24C_ReadByte(1)<<8; //左移8位
Set_Count = Num_H+Num_L; //高八位加上低八位
while(1)
{
Adjust();
display();
}
}
//-------------閃爍中斷--------------------------
void T0_INT() interrupt 1
{
TH0 = 0x3C; // 設定低位初值
TL0 = 0xB0; // 設定高位初值
n_50ms++; // 進入中斷自加
n_50ms %= 6; //10對應1Hz 取余后如果=6
if(!n_50ms)
{
flag = ~flag;
if ( num1 != Set_Count ) //設定后延時關閉閃爍
{
num2++ ;
// if( num2==3)
// { flag =0;ET0=1;TR0 = 0; num2=0 ; num1=Set_Count ;} //num2++ ;
}
}
}
復制代碼
作者:
宏達工控
時間:
2023-8-9 20:31
設置了一個標志位,可以了
if ( num1 != Set_Count ) // 設定值有變化,存入24c
{
//寫入數據
AT24C_WriteByte(0,Set_Count%256);
delay_ms(5) ; //顯示2MS
AT24C_WriteByte(1,Set_Count/256);
delay_ms(5); //顯示2MS
bc_Flag=1; //保存完成標志
num1=Set_Count ; //保存完成 將設定值送到設定值變化緩存
}
}
if( num2==3) //設定超時保存后,閃爍幾次關閉閃爍
{ET0=1;TR0 = 0; num2=0 ; bc_Flag=0;flag=0;} //num2++ ;
}
//中斷內
if ( bc_Flag==1 ) //設定后延時關閉閃爍
{
num2++ ;
}
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1