?? 新建_文本文檔_(2).txt
字號:
/*一個完整的項目程序(原創,謝絕轉載)
這是偶剛出道的時候為一個小公司做的程序.使用的是M16.當時簽定了10年的保密協議,
不過現在那個公司已經倒閉了.現在看到這段程序的人,可以自由的修改,發布,包括
但不限于用于商業或非商業的項目中!呵呵~~~~*/
//******************************************************************************
//芯片:M16
//晶振:16.0000Mhz
//模塊:率值配料下位機程序
//******************************************************************************
#include <eeprom.h>
#include <iom16v.h>
#include <macros.h>
//*******全局宏定義*************************************************************
#define uchar unsigned char
#define HANDEL 0xAA
//*******CH451數碼管顯示********************************************************
#define CH451_RESET 0x201 //復位
#define CH451_LEFTMOV 0x300 //設置移動方式-作移
#define CH451_LEFTCYC 0x301 //設置移動方式-左循
#define CH451_RIGHTMOV 0x302 //設置移動方式-右移
#define CH451_RIGHTCYC 0x303 //設置移動方式-右循
#define CH451_SYSOFF 0x400 //關顯示、鍵盤、看門狗
#define CH451_SYSON1 0x401 //開顯示
#define CH451_SYSON2 0x403 //開顯示、鍵盤
#define CH451_SYSON3 0x407 //開顯示、鍵盤、看門狗功能
#define CH451_DSP 0x500 //設置默認顯示方式
#define CH451_BCD 0x580 //設置BCD譯碼方式
#define CH451_TWINKLE 0x600 //設置閃爍控制
#define CH451_DIG0 0x800 //數碼管位0顯示
#define CH451_DIG1 0x900 //數碼管位1顯示
#define CH451_DIG2 0xa00 //數碼管位2顯示
#define CH451_DIG3 0xb00 //數碼管位3顯示
#define CH451_DIG4 0xc00 //數碼管位4顯示
#define CH451_DIG5 0xd00 //數碼管位5顯示
#define CH451_DIG6 0xe00 //數碼管位6顯示
#define CH451_DIG7 0xf00 //數碼管位7顯示
//******************************************************************************
//全局變量
//******************************************************************************
static uchar DataBuff[600];//配比數據緩沖
static uchar RecvBuff[50];//正常命令接收緩沖
static uchar SendBuff[50];//命令發送緩沖
static int AD[8];//用來存放AD轉換電流數據[0-7]8個電流量
static int ADUp[8];//上限
static int ADDown[8];//下限
static float ADValue[8];//電流數據的參照值
static uchar STAT=1;//狀態-1.配比 2.電流
static uchar E_Index=0;//狀態-配比
static uchar P_Index=0;//狀態-電流
static uchar Warning=0;//報警標志
static uchar W_Index=1;//報警序號顯示用
static uchar F_SendMode=1;//報警序號顯示用
static uchar key_Delay=0xBF;
static char PressKey=0;//按鍵碼
uchar timer=0;//數據的刷新周期
uchar UseWarning=1;//是否使用報警
int UseCount=0;//使用總次數
static uchar PasswordStat=1;//解密狀態:1(需要一級密碼),2(需要二級密碼),3(需要三級密碼),100(已全部解密)
static uchar Password1[6];//一級密碼6個字節
static uchar Password2[6];//二級密碼6個字節
static uchar Password3[6];//三級密碼6個字節
static uchar MachineNumber[3];//機器編碼
static uchar NeedSaveFlag=0;
//******************************************************************************
//初始化函數
//******************************************************************************
//初始化看門狗
void watchdog_init(void)
{
// WDR(); //喂狗
// WDTCR = 0x1F; //WATCHDOG ENABLED - dont forget to issue WDRs (0xF=2s)
}
//初始各端口
void port_init(void)
{
DDRA = 0x00;//
PORTA = 0x00;//
DDRB = 0xBF;//DSP(7,6,5,4) LED(0,1,2,3)
PORTB = 0x00;
DDRC = 0x00;//
PORTC = 0x00;//
DDRD = 0xF0;//PS2(4,5),Sound(7)
PORTD = 0x00;
PORTD&=~BIT(PD6);//0
}
//UART0 initialisation
// desired baud rate: 9600
// actual: baud rate:9615 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = 0x86;
//UBRRL = 0x67; //set baud rate //16 M
UBRRL = 0x33; //set baud rate //8 M
UBRRH = 0x00; //set baud rate hi
UCSRB = 0xF8;
}
//call this routine to initialise all peripherals
void init_devices(void)
{
int i=0;
//stop errant interrupts until set up
CLI(); //disable all interrupts
watchdog_init();
port_init();
WDR(); //喂狗
uart0_init();
WDR(); //喂狗
ch451_init();
WDR(); //喂狗
EPInit();
WDR(); //喂狗
keyboardInit();
WDR(); //喂狗
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
WDR(); //喂狗
putled(1,0,0);
putled(2,0,0);
putled(3,0,0);
putled(4,0,0);
putled(5,0,0);
putled(6,0,0);
putled(7,0,0);
putled(8,0,0);
WDR(); //喂狗
for(i=0;i<400;i++)
DataBuff[i]=0;
WDR(); //喂狗
for(i=0;i<30;i++)
RecvBuff[i]=0;
WDR(); //喂狗
for(i=0;i<30;i++)
SendBuff[i]=0;
WDR(); //喂狗
ReadUseCount();
WDR(); //喂狗
ReadSendMode();
WDR(); //喂狗
ReadKeyDelay();
WDR(); //喂狗
ReadUseWarning();//是否使用報警
WDR(); //喂狗
ReadElectricityUpDown();//讀取電流上下限
WDR(); //喂狗
ReadElectricityValue();//讀取電流參照值
WDR(); //喂狗
ReadPasswordStat();//讀取解密狀態
WDR(); //喂狗
STAT=1;//狀態-1.配比 2.電流
WDR(); //喂狗
E_Index=0;//狀態-配比-序號
P_Index=0;//狀態-電流-序號
W_Index=1;//狀態-報警-序號
Warning=0;//是否報警
PressKey=0;//按鍵碼
NeedSaveFlag=0;//保存標志
WDR(); //喂狗
sound();
WDR(); //喂狗
delay_s(1);
WDR(); //喂狗
nosound();
WDR(); //喂狗
keyboardInit();
delay_s(1);
WDR(); //喂狗
sound();
WDR(); //喂狗
keyboardInit();
delay_s(1);
WDR(); //喂狗
nosound();
WDR(); //喂狗
keyboardInit();
//all peripherals are now initialised
}
//******************************************************************************
//延時子程序
//******************************************************************************
//延時1微秒
void delay_us(int time)
{
asm("_L2: subi R16,1");
asm(" brne _L2");
asm(" ret");
}
//延時1毫秒
void delay_ms(int time)
{
int t;
for(t=0;t<time;t++)
{
delay_us(1000);
}
}
//延時1秒
void delay_s(int time)
{
int t;
for(t=0;t<time;t++)
{
delay_ms(1000);
}
}
//******************************************************************************
//輸入輸出函數
//******************************************************************************
//向串口寫一個字節
void putuchar(uchar data)
{
delay_ms(10);
while ( !( UCSRA & (1<<UDRE)) );
UDR = data; /* Put data into buffer, sends the data */
}
//從串口讀取一個字節
uchar getuchar()
{
delay_ms(10);
while (!(UCSRA & (1<<RXC)) );
return UDR; /* Get and return received data from buffer */
}
//發送一串緩沖數據到串口
void sendComm()
{
uchar k=0;
delay_ms(300);
for(k=0;k<SendBuff[0];k++)
{
putuchar(SendBuff[k+1]);
}
}
//******************************************************************************
//AD轉換函數
//******************************************************************************
//讀取指定通道的AD值
int ReadADC( uchar channel)
{
int i;
ADMUX = 0; // Select channel 0
ADCSR = 0xc4;
ADMUX = channel; // Select channel
delay_ms(10);
ADCSR |= 0x40; // Start conversion
while (!(ADCSR & 0x10)); // Check if converstion is ready
ADCSR |= 0x10; // Clear Conversion ready flag by setting the bit
i = ADCL; // Read 8 low bits first (important)
i += (int)ADCH << 8; // Read 2 high bits and multiply with 256
return i;
}
//******************************************************************************
//模擬按鍵函數
//******************************************************************************
//初始化鍵盤,數據線=0,時鐘線=1
void keyboardInit()
{
PORTD|=BIT(PD4);
return;
/*
上電復位時的協議:
1,PC->KB (0XFF);
復位, 進行 Basic Assurance Test (BAT). 設備返回 BAT 完成代碼0xaa. 如果是鍵盤,切換到掃描碼集2.上電時也進行BAT,所以,設備插上后馬上送出 0xaa. 注意: 鍵盤回應 ACK ,所以必須把數據和時鐘pin設置成high狀 態, 并且至少500 秒! (設置方法參考i8042----端口). 之后, BAT 開始. 成功時返回 aah,失敗返回fch . 有資料說0xfe ff, f4,f5,f6不存在!?
2,KB->PC (0XFA);
0xfa - n/a - PS/2 keyboard
所有鍵上報press ,release ,repeat 事件. 掃描碼集 3 有效. 默認行為.
3,KB->PC ?。?XAA);
0xaa
BAT successful completion code. See comand 0xff.
4,PC->KB (0XF2);
0xf2 - 2*R - PS/2 Keyboard / Mouse
得到ID. 讀到 0x83 and 0xab 代表鍵盤. 從mouse讀到0x00 ,可能意味著ID以外的其他東西.
5,KB->PC ?。?XFA);
0xfa - n/a - PS/2 keyboard
所有鍵上報press ,release ,repeat 事件. 掃描碼集 3 有效. 默認行為.
6,KB->PC ?。?XAB);
7,KB->PC (0X83);
9位d0-d6 為鍵盤掃描碼 D7=0 鍵按下是發出。D7=1 鍵釋放是發出。D8=1 表示一組數據結束
D7=0也包括超時發出的。
你每發一個數據應d該延時10MS-20ms,最快速度每秒30個字符
sendkey(0xFA,0);
sendkey(0xAA,0);
delay_us(10);
sendkey(0xFA,0);
sendkey(0xAB,0);
sendkey(0x83,0);
// PORTD|=BIT(PD5);//SCK=!SCK;//1
// PORTD|=BIT(PD4);//SCK=!SCK;//1
//PORTD&=~BIT(PD5);//SCK=!SCK;//0
//PORTD&=~BIT(PD4);//SCK=!SCK;//0
*/
}
//向鍵盤口發送一個字節,PS2發送程序,每次發送一個字節。
void sendkey(unsigned char KeyData,uchar WithDog)
{
// 低位在前,一個校驗位,一個停止位
unsigned char i;
unsigned char ParityBit;
unsigned char DataBit;
unsigned char delaytime=0;
if(WithDog)
{
WDR(); //喂狗
delay_ms(key_Delay);
delay_ms(20);
delaytime=13;
}
else
{
delay_ms(key_Delay*10);
delay_ms(200);
delaytime=130;
}
while(!(PORTD&BIT(PD4))>>4)
{
if(WithDog)
delay_s(10);
else
delay_s(1);
}
PORTD|=BIT(PD4);
PORTD|=BIT(PD5);
for(i=0;i<8;i++)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -