📄 main._c
字号:
//ICC-AVR application builder : 2005-10-22 20:39:47
// Target : M32 ,Fuse: 0xAF,0xD4 BLB11:0 BLB12:0
// Crystal: 8.000000Mhz
// LCD: 北京青云LCM2401281 (T6963驱动),模拟时序驱动
// 注意:0x7C00-0x7fff 保留为bootloader区 (512Word)
#include <iom32v.h>
#include <macros.h>
#include <eeprom.h>
#include "stdarg.h"
#include "stdio.h"
//英文及中文字模图标
#include "ZM.H"
#define uchar unsigned char
#define uint unsigned int
#define cchar const unsigned char
#ifndef StructRowandcol
struct rowandcol
{
uchar row;
uchar col;
};
#define StructRowandcol
#endif
#ifndef UnionAddress
union address
{
uint a;
struct
{
uchar ah;
uchar al;
}apart;
};
#define UnionAddress
#endif
union uint2uchars
{
uint uintx;
uchar ucharx[2];
};
//LCD Size
#define LCD_LEFT 0
#define LCD_TOP 0
#define LCD_RIGHT 239
#define LCD_BOTTOM 127
#define LCD_DELAY 0
//LCD功能引脚定义
#define LCD_RW PD7
#define LCD_RD PD4
#define LCD_CE PD5
#define LCD_CD PD3
#define LCD_RES PD6
#define LCD_CODE_P PORTD
#define LCD_RW_H LCD_CODE_P |= BIT(LCD_RW)
#define LCD_RW_L LCD_CODE_P &= ~BIT(LCD_RW)
#define LCD_RD_H LCD_CODE_P |= BIT(LCD_RD)
#define LCD_RD_L LCD_CODE_P &= ~BIT(LCD_RD)
#define LCD_CE_H LCD_CODE_P |= BIT(LCD_CE)
#define LCD_CE_L LCD_CODE_P &= ~BIT(LCD_CE)
#define LCD_CD_H LCD_CODE_P |= BIT(LCD_CD)
#define LCD_CD_L LCD_CODE_P &= ~BIT(LCD_CD)
#define LCD_RES_H LCD_CODE_P |= BIT(LCD_RES)
#define LCD_RES_L LCD_CODE_P &= ~BIT(LCD_RES)
#define LCD_DATA PINC
#define LCD_DDR DDRC
#define LCD_PORT PORTC
/***********************************************************************************/
// ASCII 字模宽度及高度定义
#define ASC_CHR_WIDTH 8
#define ASC_CHR_HEIGHT 12
//定义ASCII码
#define STX 0x02
#define ETX 0x03
#define EOT 0x04
#define ENQ 0x05
#define BS 0x08
#define CR 0x0D
#define LF 0x0A
#define DLE 0x10
#define ETB 0x17
#define SPACE 0x20
#define COMMA 0x2C
// T6963C 命令定义
#define LC_CUR_POS 0x21 // 光标位置设置
#define LC_CGR_POS 0x22 // CGRAM偏置地址设置
#define LC_ADD_POS 0x24 // 地址指针位置
#define LC_TXT_STP 0x40 // 文本区首址
#define LC_TXT_WID 0x41 // 文本区宽度
#define LC_GRH_STP 0x42 // 图形区首址
#define LC_GRH_WID 0x43 // 图形区宽度
#define LC_MOD_OR 0x80 // 显示方式:逻辑“或”
#define LC_MOD_XOR 0x81 // 显示方式:逻辑“异或”
#define LC_MOD_AND 0x82 // 显示方式:逻辑“与”
#define LC_MOD_TCH 0x83 // 显示方式:文本特征
#define LC_DIS_SW 0x90 // 显示开关:D0=1/0:光标闪烁启用/禁用;
// D1=1/0:光标显示启用/禁用;
// D2=1/0:文本显示启用/禁用;
// D3=1/0:图形显示启用/禁用;
#define LC_CUR_SHP 0xA1 // 光标形状选择:0xA0-0xA7表示光标占的行数
#define LC_AUT_WR 0xB0 // 自动写设置
#define LC_AUT_RD 0xB1 // 自动读设置
#define LC_AUT_OVR 0xB2 // 自动读/写结束
#define LC_INC_WR 0xC0 // 数据一次写,地址加1
#define LC_INC_RD 0xC1 // 数据一次读,地址加1
#define LC_DEC_WR 0xC2 // 数据一次写,地址减1
#define LC_DEC_RD 0xC3 // 数据一次读,地址减1
#define LC_NOC_WR 0xC4 // 数据一次写,地址不变
#define LC_NOC_RD 0xC5 // 数据一次读,地址不变
#define LC_SCN_RD 0xE0 // 屏读
#define LC_SCN_CP 0xE8 // 屏拷贝
#define LC_BIT_OP 0xF0 // 位操作:D0-D2:定义D0-D7位;D3:1置位;0:清除
const uchar *OperPowerCode[4]={"低 ","中 ","高 ","超高"};
#define CompanyName "江苏镇江爱邦电子科技有限公司"
//定义全局变量
uchar Freq_H,keycounter,keydirection; //Freq频率,KEY键值,key-direct
uchar mSEC,UpdateFlag,S_flag;
uint Freq,lastfreq;
uchar DisplayBuffer[7]; //显示数据缓冲
uchar gCurRow,gCurCol; // 当前行、列存储,行高16点,列宽8点
//蜂鸣器接PortB.1
#define beep (1<<1)
#define beep_1() (PORTB |=beep)
#define beep_0() (PORTB &=~beep)
#define beep_off() (PORTB |=beep)
#define beep_on() (PORTB &=~beep)
//8MHz时钟,1uS精确延时
//#define delay_1us() asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop")
//7.3728MHz时钟,~1uS延时
#define delay_1us() asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop")
//延时N微秒
void delay_us(uint us)
{
while(us--) {
delay_1us();
}
}
//延时N毫秒
void delay_ms(uint ms) {
while(ms--) {
delay_us(1000);
}
}
//蜂鸣器讯响
void beeps(unsigned char i) {
while(i--) {
beep_on();
delay_ms(30);
beep_off();
delay_ms(30);
}
}
//DDRxn PortX I/O 上拉
// 0 0 input off 三态
// 0 1 input on 弱上拉
// 1 0 output off 推挽0
// 1 1 output off 推挽1
//端口初始化
void port_init(void)
{
PORTA = 0x1C; //&B000,111,00 '0x1C
DDRA = 0xE0; //&B111,000,00 porta.7-porta.2 Kekyscan,1:0 ADC input '0xE0
PORTB = 0xF3; //portb.2,3=0
DDRB = 0xFE;
PORTC = 0xFF; //m103 output only
DDRC = 0x00;
PORTD = 0xFF;
DDRD = 0xFA; //PD.0(RXD),PORTD.2(INT0)=input,&B1111,1010
}
//Watchdog initialize
// prescale: 2048K
void watchdog_init(void)
{
WDR(); //this prevents a timout on enabling
WDTCR = 0x0F; //WATCHDOG ENABLED - dont forget to issue WDRs
}
//TIMER0 initialize - prescale:Falling edge
// WGM: Normal
// desired value: 1Hz
// actual value: Out of range
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x00 /*INVALID SETTING*/; //set count
OCR0 = 0x00 /*INVALID SETTING*/; //set compare
TCCR0 = 0x06; //start timer
}
//T0计数器中断
#pragma interrupt_handler timer0_ovf_isr:12
void timer0_ovf_isr(void)
{
Freq_H++; //外部脉冲计数用于测量频率
TCNT0 = 0x00; //reload counter value
}
//*
//7.3728MHz
//TIMER1 initialize - prescale:1024
// desired value: 100mSec
// actual value: 100.000mSec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xFD; //setup
TCNT1L = 0x30;
OCR1AH = 0x02;
OCR1AL = 0xD0;
OCR1BH = 0x02;
OCR1BL = 0xD0;
ICR1H = 0x02;
ICR1L = 0xD0;
TCCR1A = 0x00;
TCCR1B = 0x05; //start Timer
}
//*/
#pragma interrupt_handler timer1_ovf_isr:10
void timer1_ovf_isr(void)
{
//TIMER1 has overflowed
TCNT1H = 0xFD; //reload counter high value
TCNT1L = 0x30; //reload counter low value
//ms100_flag=1; //100mS标志置位
UpdateFlag=1; //100mS标志置位
if (S_flag<9) S_flag++; //1S标志置位
else
{
TCNT0=0;
S_flag=0;
Freq=Freq_H*256+TCNT0;
Freq_H=0;
}
}
//*/
//ADC initialize
// Conversion time: 208uS
void adc_init(void)
{
ADCSR = 0x00; //disable adc
ADMUX = 0x00; //select adc input 0
ACSR = 0x80;
ADCSR = 0xEF; //0xEE
}
#pragma interrupt_handler adc_isr:17
void adc_isr(void)
{
//conversion complete, read value (int) using...
// readadc=ADCL; //Read 8 low bits first (important)
}
//*/
//串行通讯设置
//UART0 initialize
// 7.3728MHz
// desired baud rate: 57600
// actual: baud rate:57600 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x07; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
//*/
/*8MHz
//UART0 initialize
// desired baud rate: 19200
// actual: baud rate:19231 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x19; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
//*/
//串行通讯接受中断入口服务程序
#pragma interrupt_handler uart0_rx_isr:14
void uart0_rx_isr(void)
{
//uart has received a character in UDR
}
//串口发送字符串
void uart_str(unsigned char *str) {
while(*str)
{
while (!(UCSRA&(1<<UDRE)));
UDR=*str++;
}
}
//等待发送完一个字节
void wait_tx() {
while(!(UCSRA&0x40));
UCSRA|=0x40;
}
//外部中断0,用于编码开关解码,解码图:
//A -|
// | -----|__________|----------|____________
//C -|
//
//B -|
// | ----------|__________|----------|____________
//C -|
// CW ===>>> ROTATION
//外部中断设置(ISC01=0,ISC00=1): INT0 引脚上任意的逻辑电平变化都将引发中断
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
//external interupt on INT0
GICR=0; //禁止外部中断
if ((PIND & 0x04)==0) //先判断是高电平产生的中断还是低点平的中断
if ((PINA & 0x02)==0)
{
keycounter--;
keydirection=0;
}
else
{
keycounter++;
keydirection=1;
}
//beeps(1);
else
if ((PINA & 0x02)==0)
{
keycounter++;
keydirection=1;
}
else
{
keycounter--;
keydirection=0;
}
GICR=0x40;
}
//**********************************************************************************
//**********************************************************************************
//T6963 LCD 显示模块驱动代码段
//**********************************************************************************
//**********************************************************************************
/*发送单字节数据到LCD屏*/
void lcd_wd(uchar lcd_data)
{
LCD_DDR = 0X00;
LCD_CODE_P &= ~(BIT(LCD_RD) | BIT(LCD_CE));
/*LCD_CODE_P = 0XF9;*/
while((LCD_DATA & 0X03) != 0X03);
LCD_RD_H;
LCD_CD_L;
LCD_RW_L;
/*LCD_CODE_P = 0XF2;*/
LCD_DDR = 0XFF;
LCD_PORT = lcd_data;
asm("NOP");
LCD_CODE_P |= (BIT(LCD_RW) | BIT(LCD_RD) | BIT(LCD_CD) | BIT(LCD_CE));
asm("NOP");
asm("NOP");
}
/***********************************************************************************/
void lcd_wc(uchar lcd_code)/*写单字节命令*/
{
LCD_DDR = 0X00;
LCD_CODE_P &= ~(BIT(LCD_RD) | BIT(LCD_CE));
/*LCD_CODE_P = 0XF9;*/
while((LCD_DATA & 0X03) != 0X03);
LCD_RD_H;
LCD_RW_L;
/*LCD_CODE_P = 0XFA;*/
LCD_DDR = 0XFF;
LCD_PORT = lcd_code;
LCD_CODE_P |= (BIT(LCD_RW) | BIT(LCD_RD) | BIT(LCD_CD) | BIT(LCD_CE));
}
/***********************************************************************************/
//写带2字节参数的指令
void lcd_wc3(uchar lcd_code,uchar lcd_data1,uchar lcd_data2)
{
lcd_wd(lcd_data1);
lcd_wd(lcd_data2);
lcd_wc(lcd_code);
}
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -