?? main.c
字號:
/********************************************************************
* 主 頁 : HTTP://WWW.QLMCU.COM
*
* 程序功能 : 時鐘演示程序、蜂鳴器、發光二極管測試、LCD1602測試
*
* 應用軟件 : WinAVR
*
* 版 本 : WinAVR-20050214-install
*
* 硬 件 : WS9500 (工作頻率: 6MHz)
*
* 創建時間 : 2005-11-10
*
* 編 寫: benladn911
*
* 注:為了有更多實用的實驗程序供大家學習,部分程序參考網上的資源,
* 在此謝謝這些無私奉獻的朋友!!!
*
********************************************************************/
#include"avr/io.h" //頭文件
#include <avr/delay.h> //延時函數
#include"avr/interrupt.h" //中斷處理函數
#include"avr/signal.h" //中斷處理函數
#define uchar unsigned char
#define uint unsigned int
//內部函數_delay_ms() 最高延時 262.144mS@1MHz 即 32.768ms@8MHz
void delay_ms(unsigned int ms);//----ms級延時
//內部函數_delay_us() 最高延時 768 us@1MHz 即 96 us@8MHz
void delay_us(unsigned int us);//----us級延時
void BEEP(void);//----蜂鳴器子程序
//-----------位操作定義------------------------
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define BEEP_ON cbi(PORTD,2)//在程序用BEEP_ON代替cbi(PORTD,2)
#define BEEP_OFF sbi(PORTD,2)//在程序用BEEP_OFF代替sbi(PORTD,2)
#define LED_ON cbi(PORTD,7)//在程序用LED_ON代替cbi(PORTD,7)
#define LED_OFF sbi(PORTD,7)//在程序用BEEP_ON代替sbi(PORTD,7)
//數碼管字型表,對應0,1,2,3,4,5,6,7,8,9//
uchar Table[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};
uchar Data[6]={0,0,0,0,0,0}; //顯示初始值:0 0 0 0 0 0
uchar CNT=0; //初始計數值:0
uchar Timer[3]={0x00,0x00,0x00}; //初始時間00:00:00
//--------------------------------------------------------------------------
//定義MCU與LCD的接口
#define LCD_RS_PORT PORTC
#define LCD_EN_PORT PORTC
#define LCD_RW_PORT PORTC
#define LCD_DATA_PORT PORTA
#define LCD_DATA_DDR DDRA
#define LCD_DATA_PIN PINA
#define LCD_RS (1<<5) //PORTC5 out
#define LCD_EN (1<<7) //PORTC7 out
#define LCD_RW (1<<6) //PORTC6 out/in
#define LCD_DATA 0xf0 //PORTA4/5/6/7 out
//-------函數聲明------------------------------------------------------------
void LCD_init (void);
void LCD_en_write (void);
void LCD_write_char (unsigned command,unsigned data);
void LCD_wait_Ready (void);
void LCD_set_xy (unsigned char x, unsigned char y);
void LCD_write_string (unsigned char X,unsigned char Y,unsigned char *s);
//--------------------------------------------------------------------------
/*----------------------------------------------------
光標命令
LCD_write_char(0x0e,0); //光標開
LCD_write_char(0x0d,0); //光標所在字符閃爍
LCD_write_char(0x0c,0); //光標關
-------------------------------------------------------*/
//----------------ms級延時---------------
void delay_ms(unsigned int ms)
{
unsigned int i;
for(i=0;i<ms;i++) _delay_ms(1); //延時 i*ms= 毫秒,可自行調節
}
//----------------us級延時---------------
void delay_us(unsigned int us)
{
unsigned int i;
for(i=0;i<us;i++) _delay_us(1); //延時 i*us= 毫秒,可自行調節
}
//-------------------- 數碼管動態掃描程序------------------------
void Display(uchar *p) //動態顯示函數,參數p為待顯示的數組名
{
//-----------------第一種動態掃描方式-----------------
uchar i,sel=0b11111110;
for(i=0;i<6;i++)
{
PORTB=sel; //選通最右邊的數碼管
PORTA=Table[p[ i ]]; //送字型碼
delay_ms(2); //顯示延時
sel=(sel<<1)|0b00000001; //移位以顯示前一位
}
/*//-------------第二種動態掃描方式-----------------
uchar i=0,sel=0b11111110;
PORTB=sel;
PORTA=Table[p[ i ]]; //送字型碼
delay_ms(2); //顯示延時
i++;
sel=0b11111101;
PORTB=sel;
PORTA=Table[p[ i ]]; //送字型碼
delay_ms(2); //顯示延時
i++;
sel=0b11111011;
PORTB=sel;
PORTA=Table[p[ i ]]; //送字型碼
delay_ms(2); //顯示延時
i++;
sel=0b11110111;
PORTB=sel;
PORTA=Table[p[ i ]]; //送字型碼
delay_ms(2); //顯示延時
i++;
sel=0b11101111;
PORTB=sel;
PORTA=Table[p[ i ]]; //送字型碼
delay_ms(2); //顯示延時
i++;
sel=0b11011111;
PORTB=sel;
PORTA=Table[p[ i ]]; //送字型碼
delay_ms(2); //顯示延時
*/
}
//計數值處理函數。參數p1:時間數組名;參數p2:顯示數組名//
//功能:此函數用于將計數值拆分為BCD碼的10時,時,10分,分,10秒,秒//
void Process(uchar *p1,uchar *p2)
{
p2[0]=p1[0]/10;
p2[1]=p1[0]-p2[0]*10;
p2[2]=p1[1]/10;
p2[3]=p1[1]-p2[2]*10;
p2[4]=p1[2]/10;
p2[5]=p1[2]-p2[4]*10;
}
//--------------初始化I/O口------------------
void Init_IO(void) //初始化I/O口
{
DDRA=0xff; //設置A口為推挽1輸出
PORTA=0xff;
DDRB=0xff; //DDRC=0xff; //設置C口為推挽1輸出;
PORTB=0xff; //PORTC=0xff;
}
//-------------------主程序--------------------
int main(void)
{
delay_ms(1000);
DDRA = 0XFF;
//DDRA |= LCD_DATA ;//
DDRC = 0XFF;
//DDRC |= LCD_RS | LCD_EN | LCD_RW ; //
LCD_init();//初始化
delay_ms(100);
LCD_init();//初始化
delay_ms(100);
LCD_write_char(0x01,0); //顯示清屏
delay_ms(200);
LCD_write_char(0x01,0); //顯示清屏
delay_ms(500);
LCD_write_string(1,0,"WWW.QLMCU.COM");
delay_ms(200);
LCD_write_string(1,1,"0595-22313231");
delay_ms(1000);
Init_IO();//初始化I/O口
PORTA=0X00;//測試發光二極管
sbi(DDRD,7);
LED_ON;
BEEP();//測試蜂鳴器
delay_ms(500);
BEEP();
delay_ms(500);
BEEP();
delay_ms(2000);//延時
PORTB=0xff; //熄滅所有的數碼管
LED_OFF;//關閉發光二極管
PORTA=0XFF;
TCCR0=0x04;//T/C0工作于定時方式,系統時鐘256分頻
TCNT0=0x06;//計數初始值6
TIMSK=0x02;//開放TOV0中斷
SREG=SREG|0x80;//開放總中斷
while(1)
{
Process(Timer,Data); //計數值處理
Display(Data); //動態掃描顯示
}
}
//---------------------T/C0中斷服務函數-------------------------
SIGNAL(SIG_OVERFLOW0)
{
TCNT0=0x06; //重裝計數初始值6
CNT++; //中斷次數累加
if(CNT==125)
{CNT=0; //計數到125次,計數值復位
Timer[2]++; //秒加1
if(Timer[2]==60)
{Timer[2]=0;
Timer[1]++;
} //分進位
if(Timer[1]==60)
{Timer[1]=0;
Timer[0]++;
} //時進位
if(Timer[0]==24)
{Timer[0]=0;
}
} //計數到達最高位,計數復位
}
//---------------蜂鳴器子程序-------------
void BEEP(void)
{
unsigned int j;
sbi(DDRD,2);//把PB2設置為輸出(蜂鳴器)
for(j=200;j>0;j--)
{
BEEP_ON;delay_us(500);
BEEP_OFF;delay_us(40);//2.5KHz
}
delay_us(10);
for(j=200;j>0;j--)
{
BEEP_ON;delay_us(600);
BEEP_OFF;delay_us(40);//1.25KHz
}
delay_us(5);
for(j=200;j>0;j--)
{
BEEP_ON;delay_us(600);
BEEP_OFF;delay_us(40);//1.25KHz
}
}
/*---------------LCD初始化----------------*/
void LCD_init(void)
{
delay_ms(1000);
LCD_write_char(0x28,0); //4bit Display
delay_ms(30);
LCD_write_char(0x28,0); //4bit Display
delay_ms(30);
LCD_write_char(0x28,0); //4bit Display
delay_ms(30);
LCD_write_char(0x28,0); //4bit Display
delay_ms(30);
LCD_write_char(0x0c,0); //顯示開
delay_ms(30);
LCD_write_char(0x0c,0); //顯示開
delay_ms(30);
LCD_write_char(0x01,0); //顯示清屏
delay_ms(30);
LCD_write_char(0x01,0); //顯示清屏
delay_ms(30);
LCD_write_char(0x06,0); //顯示光標移動設置
delay_ms(30);
}
/*---------------寫入使能---------------*/
void LCD_en_write(void) //EN端產生一個高電平脈沖,寫LCD
{
LCD_EN_PORT |= LCD_EN;
delay_us(20);
LCD_EN_PORT &= ~LCD_EN;
delay_us(20);
}
/*-----------------------------------------------------------------------
LCD_write_char : 英文字符串顯示函數
輸入參數:*s :英文字符串指針;
X、Y : 顯示字符串的位置,X:0-15,Y:0-1
LCD第一行顯示寄存器地址:0X80-0X8F
LCD第一行顯示寄存器地址:0XC0-0XCF
編寫日期 :2005-10-7
最后修改日期 :
-----------------------------------------------------------------------*/
void LCD_write_char(unsigned command,unsigned data)
{
unsigned command_temp,data_temp;
command_temp = command;
data_temp = data;
LCD_wait_Ready();
LCD_RW_PORT &= ~LCD_RW; //RW=0
LCD_DATA_PORT &= 0X0f;
if (command == 0)
{
LCD_RS_PORT |= LCD_RS; //RS=1
LCD_DATA_PORT |= data_temp&0xf0; //send high 4bit
}
else
{
LCD_RS_PORT &= ~LCD_RS; //RS=0
LCD_DATA_PORT |= command_temp&0xf0;//send high 4bit
}
LCD_en_write();
LCD_DATA_PORT &= 0X0f;
command_temp=command_temp << 4; //send low 4bit
data_temp=data_temp << 4;
if (command==0)
LCD_DATA_PORT |= data_temp&0xf0;
else
LCD_DATA_PORT |= command_temp&0xf0;
LCD_en_write();
LCD_RW_PORT |= LCD_RW;
LCD_RS_PORT ^= LCD_RS;
}
void LCD_wait_Ready(void) //等待LCD空閑
{
LCD_DATA_DDR &= ~0x80; //PD7 I/O口方向設置為輸入
LCD_RW_PORT |= LCD_RW; //RW=1
LCD_RS_PORT &= ~LCD_RS; //RS=0
LCD_EN_PORT |= LCD_EN; //EN=1
while (!( LCD_DATA_PIN&0x80 ) == 0); //RW=1,讀PD7,為0表示空閑;
LCD_EN_PORT &= ~LCD_EN; //EN=0
LCD_DATA_DDR |= 0xf0;
}
/*-----------------------------------------------------------------------
LCD_set_xy : 設置LCD顯示的起始位置
輸入參數:x、y : 顯示字符串的位置,X:0-15,Y:0-1
LCD第一行顯示寄存器地址:0X80-0X8F
LCD第一行顯示寄存器地址:0XC0-0XCF
編寫日期 :2005-10-7
最后修改日期 :
-----------------------------------------------------------------------*/
void LCD_set_xy( unsigned char x, unsigned char y )
{
unsigned char address;
if (y == 0) address = 0x80 + x;
else
address = 0xc0 + x;
LCD_write_char( address, 0 );
}
/*-----------------------------------------------------------------------
LCD_write_string : 英文字符串顯示函數
輸入參數:*s :英文字符串指針;
X、Y : 顯示字符串的位置
編寫日期 :2005-10-7
最后修改日期 :
-----------------------------------------------------------------------*/
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)
{
LCD_set_xy( X, Y );
while (*s)
{
LCD_write_char( 0, *s );
s ++;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -