📄 m16pwm-led._c
字号:
////////////////////////////////////////////////////////////////////////////////
//ICC-AVR application builder : 2006-8-1 上午 08:05:37
// Target : M16
// Crystal: 16.0000Mhz
// ADc2采集转把信号
////////////////////////////////////////////////////////////////////////////////
#include <iom16v.h>
#include <macros.h>
#define fre 125
#define uchar unsigned char
#define uint unsigned int
unsigned char kk;
int k;
uchar temp_data,hour_data,minut_data,second_data,second_flag;
uchar AdResult=0;
uchar SpeedMode=0;//SpeedMode=0 手动模式;SpeedMode=0x55 巡航模式
uchar SpeedVal=0;//保存当前速度参数,用于巡航模式
uchar M8Mode=0x0;//M8控制字=Rev,Rev,Rev,RevMode,Rev,Rev,LEFT_LED,RIGHT_LED
uchar LedTab[16]={0xEB,0x41,0xB3,0xBA,0x78,0xDA,0xDB,0xA8,0xFB,0xFA,
0xF9,0xFB,0xC3,0xEB,0xD3,0xD1};
uchar LedBuf[2]={0,0};
uchar LedDp=0;
uchar UartBuf[10],UartBufCount=0;
uchar LRledReg=0;
////////////////////////////////////////////////////////////////////////////////
//function declare
void port_init(void);
void uart0_init(void);
void uart0_rx_isr(void);
void uart0_tx(uchar tdata);
void tx_pack(void);
void timer1_init(void);
void timer1_comp_isr(void);
void led_display(uchar delay);
void HexToDec(uchar hex,uchar dec);
void ms_delay(uint delay);
void init_devices(void);
void adc_init(void);
////////////////////////////////////////////////////////////////////////////////
void port_init(void)
{
PORTA = 0xFF;
DDRA = 0xFB; //PA2=ADC2,输入
PORTB = 0xFF;
DDRB = 0x1F; //数码管片选信号,低有效,常态为高,PB4=LED-dp
PORTC = 0xFF; //m103 output only
DDRC = 0x00; //PC0,1=RL_in
PORTD = 0x9F;
DDRD = 0x78;
}
//TIMER1 initialisation - prescale:1
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Sec
// actual value: 1.000Sec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xC2; //setup
TCNT1L = 0xF7;
OCR1AH = 0x3D;
OCR1AL = 0x09;
OCR1BH = 0x3D;
OCR1BL = 0x09;
//OCR1CH = $OCR1CH$;
//OCR1CL = $OCR1CL$;
ICR1H = 0x3D;
ICR1L = 0x09;
TCCR1A = 0x00;
TCCR1B = 0x05; //start Timer
}
/***************************************************************************
****************************************************************************/
//UART0 initialize
// 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 = BIT(URSEL) | 0x06;
UBRRL = 0x67; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
/***************************************************************************
****************************************************************************/
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
uchar voldata;
//uart has received a character in UDR
UartBuf[UartBufCount++]= UDR;
if(UartBuf[0]==0xaa)//包头
{
//UartBuf[3]=Rev,Rev,Rev,Rev,Rev,Rev,LEFT_LED,RIGHT_LED
if(UartBufCount>4)
{
if( ((UartBuf[1]+UartBuf[2])==0xff)&&
((UartBuf[3]+UartBuf[4])==0xff) )
{
LedBuf[0]=UartBuf[1];//SpeedVal
voldata=UartBuf[3];
if(voldata<105)voldata=105; //电压范围21~29.5,每个码表示0.2V
// result=100*((tmpvol/5)-21)/(29.5-21)
LedBuf[1]=40*(voldata-105)/17;//+24V
}
UartBufCount=0;
}
}
else UartBufCount=0;
}
/***************************************************************************
****************************************************************************/
void uart0_tx(uchar tdata)
{
while(!(UCSRA & (1<<UDRE) ));
UDR = tdata;
}
void tx_pack(void)
{
uart0_tx(0xaa);
if(SpeedMode)
{ //巡航模式
uart0_tx(SpeedVal);
uart0_tx(0xff-SpeedVal);
}
else
{ //手动模式
uart0_tx(AdResult);
uart0_tx(0xff-AdResult);
}
uart0_tx(M8Mode);
uart0_tx(0xff-M8Mode);
}
/***************************************************************************
用于手动模式和巡航模式的选择
****************************************************************************/
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
//external interupt on INT0
if(SpeedMode)
{
SpeedMode=0;//手动模式
LedDp=0;
}
else
{
SpeedMode=0x55;//巡航模式
LedDp=0x01;
SpeedVal=AdResult;
}
}
/***************************************************************************
A/D初始化
****************************************************************************/
void adc_init(void)
{
ADCSRA =0x0; //关闭AD
ADMUX = (1<<REFS0)|(1<<ADLAR)|(1<<MUX1); //选择外部参考电源 ADC2 左对齐
ACSR = (1<<ACD); //关闭模拟比较器
ADCSRA = (1<<ADEN)|(1<<ADIF)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0);//中断允许 32分频
}
/***************************************************************************
A/D中断处理
****************************************************************************/
#pragma interrupt_handler Adc_isr:15
void Adc_isr(void)
{
uint ad_tmp;
ad_tmp=ADCH; //读取高位数据(左对齐)
if(ad_tmp>0xd0)ad_tmp=0xd0;
if(ad_tmp<0x30)ad_tmp=0x30;
ad_tmp-=0x30;
AdResult=(ad_tmp*0xff/0xa0)&0x00ff-1;
//LedBuf[0]=AdResult;
}
#pragma interrupt_handler timer1_comp_isr:9
void timer1_comp_isr(void)
{
//compare occured TCNT1=OCR1
uchar tt;
TCNT1 = 0xC2F7; //setup
//PORTD ^=0x60;
//LedDp[second_data%4]=1;
//LedBuf[0]=second_data;
if(++second_data>=60)
{
second_data=0;
if(++minut_data>=60)
{
minut_data=0;
if(++hour_data>=24)
{
hour_data=0;
}
}
}
}
//led display
void led_display(uchar delay)
{
uchar tmp0,tmp1;
tmp0=LedBuf[0];
tmp1=LedBuf[1];
if(tmp0>99)tmp0=99;
if(tmp1>99)tmp1=99;
PORTB = ~0x08;
PORTA = LedTab[(tmp0%10)];
if(LedDp&0x01)PORTB|=0x10;
else PORTB&=0xEF;
ms_delay(delay);
PORTB = ~0x04;
PORTA = LedTab[((tmp0/10)&0x0f)];
if(LedDp&0x02)PORTB|=0x10;
else PORTB&=0xEF;
ms_delay(delay);
PORTB = ~0x02;
PORTA = LedTab[(tmp1%10)];
if(LedDp&0x04)PORTB|=0x10;
else PORTB&=0xEF;
ms_delay(delay);
PORTB = ~0x01;
PORTA = LedTab[((tmp1/10)&0x0f)];
if(LedDp&0x08)PORTB|=0x10;
else PORTB&=0xEF;
ms_delay(delay);
}
void ms_delay(uint delay)
{
int d1,d2;
for(d1=0;d1<delay;d1++)
{
for(d2=0;d2<1000;d2++);
}
}
//call this routine to initialise all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
uart0_init();
timer1_init();
adc_init();
MCUCR = 0x02;
GICR = 0x40;
TIMSK = 0x04; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialised
}
////////////////////////////////////////////////////////////////////////////////
void main()
{
int i,adc=0,led=0,key=0;
uchar ttmp,leddptt=0;
init_devices();
temp_data=0x13;
while(1)
{
//display second flag
if(++led>240)
{
PORTD ^= (LRledReg<<3);//LR-LED
led=0;
M8Mode ^= (LRledReg&0x03);
}
if(++adc>100)
{
tx_pack();
ADCSRA |=(1<<ADSC); //启动AD转换
adc=0;
}
if(++key>200)
{
ttmp = PINC&0x03;
if(ttmp==0x03)
{
PORTD |=0x18;//关LR-LED
M8Mode=0;
LRledReg=0;
}
else LRledReg = (~(ttmp))&0x03;
LedDp=LedDp<<1;
if(LedDp>0x08)LedDp=0x01;
}
led_display(1);
}
}
////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -