/* Test configuration:
MCU: ATmega128
Oscillator: External Clock 07.37280 MHz
Ext. Modules: -
SW: mikroC PRO for AVR
*/
// BCD 指撥開關實驗
// Com 4 --> PC7
// Com 3 --> PC6
// Com 2 --> PC5
// Com 1 --> PC4
// BCD PUshwheel 8--> pc3
// BCD PUshwheel 4--> pc2
// BCD PUshwheel 2--> pc1
// BCD PUshwheel 1--> pc0
//
// LCD module connections
sbit LCD_RS at PORTF1_bit;
sbit LCD_EN at PORTF3_bit;
sbit LCD_D4 at PORTA4_bit;
sbit LCD_D5 at PORTA5_bit;
sbit LCD_D6 at PORTA6_bit;
sbit LCD_D7 at PORTA7_bit;
sbit LCD_RS_Direction at DDF1_bit;
sbit LCD_EN_Direction at DDF3_bit;
sbit LCD_D4_Direction at DDA4_bit;
sbit LCD_D5_Direction at DDA5_bit;
sbit LCD_D6_Direction at DDA6_bit;
sbit LCD_D7_Direction at DDA7_bit;
// End LCD module connections
#define uchar unsigned char
#define uint unsigned int
#define BCD_Data_IO PORTC //BCD PUshwheel DATA PORT
#define BCD_Data_DDR DDRC //BCD PUshwheel DATA方向REG.
#define BCD_Data_IN PINC
#define Data_IO PORTA //LCD 1602 DATA PORT
#define Data_DDR DDRA //LCD 1602 DATA方向REG.
#define D_LE0 PORTD &= ~(1 << B4) //七段顯示器 段控制位為0,Latch port data
#define D_LE1 PORTD |= (1 << B4) //七段顯示器 段控制位為1
#define W_LE0 PORTD &= ~(1 << B5) //七段顯示器 位控制位為0
#define W_LE1 PORTD |= (1 << B5) //七段顯示器 位控制位為1
sbit D_LE at PORTD4_bit; // Output pin, PINx register is used
sbit W_LE at PORTD5_bit; // Output pin, PINx register is used
sbit D_LE_Pin_Direction at DDD4_bit;
sbit W_LE_Pin_Direction at DDD5_bit;
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLRBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define CHKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))
char key_checkin[4],key_check[4], disp[5],i,j,scanFg=0;
unsigned int tempcnt, countval=0 ;
//
// system_init()子程序
//
void system_init()
{
Data_DDR=0xFF; //方向輸出
Data_IO=0xFF; //Set
D_LE_Pin_Direction = 1; // Set pin as output ;
W_LE_Pin_Direction = 1; // Set pin as output ;
D_LE0; //關掉七段顯示器,以免顯示亂碼
W_LE0;
BCD_Data_DDR=0xF0; //High Nibble 輸出 Low Nibble 輸入
BCD_Data_IO=0x0F; //Set
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
}
//
// 鍵盤掃瞄子程序,採用逐鍵掃瞄的方式
//
void BCDkeyscan(void)
{
uchar i,j=0x80,k=1;
BCD_Data_DDR=0xf0; //在IO口由輸出方式變為輸入方式時要延遲一個週期
BCD_Data_DDR=0xf0; //採取寫兩次的方法延時
for (i=0;i<=3;i++)
{
BCD_Data_IO=j;
key_checkin[3-i]= (BCD_Data_IN) & 0x0f;
j=j>>1;
}
delay_ms(20);
j=0x80;
for (i=0;i<=3;i++)
{
BCD_Data_IO=j;
key_check[3-i]= (BCD_Data_IN) & 0x0f;
j=j>>1;
}
scanFg=1;
for (i=0;i<=3;i++)
{
if (key_check[i]!=key_checkin[i])
scanFg=0;
}
}
//
// check current value equal setting value
//
void check_equal(void)
{
scanFg=1; //equal
for (i=0;i<=3;i++)
{
if (disp[i]!=key_check[i])
scanFg=0; //not equal
}
}
//
// display current value
//
void display_cunt_val(void)
{
tempcnt=countval;
disp[5]= tempcnt/100000; //countval value 0..655356
tempcnt= tempcnt%100000;
disp[4]= tempcnt/10000; //countval value 0..655356
tempcnt= tempcnt%10000;
disp[3]= tempcnt/1000;
tempcnt= tempcnt%1000;
disp[2]= tempcnt/100;
tempcnt= tempcnt%100;
disp[1]= tempcnt/10;
disp[0]= tempcnt%10;
Lcd_Chr(1,16,disp[0]+0x30);
Lcd_Chr(1,15,disp[1]+0x30);
Lcd_Chr(1,14,disp[2]+0x30);
Lcd_Chr(1,13,disp[3]+0x30);
}
//
// 主函數
//
void main()
{
system_init();
countval=0;
Lcd_Out(1,1,"BCD PushWheel SW"); // Write text in second row
Lcd_Out(2,1,"WheelCode:"); // Write text in second row
DELAY_MS(1000);
scanFg=1;
BCDkeyscan(); //scan BCD 指撥開關
do {
BCDkeyscan();
if (scanFg!=0)
{
Lcd_Chr(2,11,key_check[3]+0x30
Lcd_Chr(2,12,key_check[2]+0x30
Lcd_Chr(2,13,key_check[1]+0x30
Lcd_Chr(2,14,key_check[0]+0x30
}
delay_ms(50);
countval++;
Lcd_Out(1,1,"Count Value: ");
display_cunt_val();
check_equal();
if (scanFg!=0) countval=0; //if count to set value then
// reset current count
} while (1);
}