📄 m8pwm.c.bak
字号:
/******************************************************************************
程序名称:电机驱动程序
运行平台:ATMaga8 12m晶振
程序说明:通过输入来调节pw波
pc3 作为ad输入
PD5=运行状态指示灯
pb0=左转灯,pb1=右转灯,pb=0时灯亮, 左右灯同时亮起为刹车状态
2007-12-24
******************************************************************************/
#include <iom8v.h>
#include <macros.h>
#pragma interrupt_handler Timer1a_c:7 //计算速度信息
#pragma interrupt_handler Adc_isr:15 // 采集握把信号
#pragma interrupt_handler int0_isr:2 //用于计算每秒钟后轮转过的半圈数
#pragma interrupt_handler int1_isr:3 //用于相应刹车
#pragma interrupt_handler uart0_rx_isr:12//串口接收程序
#define BRAKE_LED_ON PORTC |=0x03
#define BRAKE_LED_OFF PORTC &=0xfc
#define LEFT_LED_ON PORTC |=0x01
#define LEFT_LED_OFF PORTC &=0xfe
#define RIGHT_LED_ON PORTC |=0x02
#define RIGHT_LED_OFF PORTC &=0xfd
//Variable
unsigned char AdResult=0x10; //保存AD结果
unsigned char SpeedVal=0; //速度
unsigned char RolCount=0; //每秒钟后轮转过的半圈数
unsigned char UartBuf[10],UartBufCount=0;
unsigned char LrLedReg=0; //用于保存刹车灯的状态,以便在刹车释放后回复
/***************************************************************************/
/***************************************************************************/
void Port_init(void);
void uart0_init(void);
void uart0_tx(unsigned char tdata);
void Timer0_init(void);
void Timer1_init(void);
void Timer2_init(void);
void Timer1a_c(void);
void Hardware_init(void);
void Delay_ms(unsigned int delay_time);
void adc_init(void);
/***************************************************************************
端口初始化
****************************************************************************/
void Port_init(void)
{
PORTB=0b11110111;
DDRB =0b00001000; //PB3用来输出pw波
PORTC=0b11111100;
DDRC =0b00100011; //pc0,1=LR_led,Pc5=led in
//PORTD=0xff;
//DDRD =0xe0; // d6d7=lr_led
}
/***************************************************************************
串口0初始化
****************************************************************************/
// 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 = 0x4D; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
/***************************************************************************
定时器1初始化
****************************************************************************/
//定时器1主要用来做速度扫描
void Timer1_init(void)
{
//定时器1部分 ,1024分频,定时1s
TCNT1H = 0xE0;
TCNT1L = 0xC0;
OCR1AH = 0x2D;
OCR1AL = 0xC5;
TCCR1B = (0x01<<CS12)|(0x01<<CS10)|(0x01<<WGM12);//ctc
}
/***************************************************************************
Timer2初始化 ,PWM
****************************************************************************/
// desired value: 20KHz
// actual value: 20.000KHz (0.0%)
//定时器0用来产生PW波
void Timer2_init(void)
{
TCCR2 = 0x00; //stop
ASSR = 0x00; //set async mode
TCNT2 = 0x0; //setup
OCR2 = 0x19;//设置OCR2
TCCR2 = 0x79; //8M/8=1MHz,0x79
}
/***************************************************************************
A/D初始化
****************************************************************************/
void adc_init(void)
{
ADCSRA =0x0; //关闭AD
ADMUX = (1<<REFS0)|(1<<ADLAR)|(1<<MUX1)|(1<<MUX0); //选择外部参考电源 ADC3 左对齐
ACSR = (1<<ACD); //关闭模拟比较器
ADCSRA = (1<<ADEN)|(1<<ADIF)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0);//中断允许 32分频
}
/***************************************************************************
A/D中断处理
****************************************************************************/
void Adc_isr(void)
{
AdResult=ADCH; //读取高位数据(左对齐)
//OCR2 = 0xff - AdResult; //更新PWM参数
}
/***************************************************************************
定时器1中断处理程序
****************************************************************************/
void Timer1a_c(void)
//1s中断程序,用于检测转速
{
SpeedVal=RolCount*1.13; //3.1415*3.6*后轮半径(0.1m)=1.13
RolCount=0;
}
/***************************************************************************
外部中断0处理程序
****************************************************************************/
void int0_isr(void)
{
//external interupt on INT0
RolCount++;//半圈数增加
}
/***************************************************************************
外部中断1处理程序
****************************************************************************/
void int1_isr(void)
{
//external interupt on INT1
if(MCUCR&(0x01<<ISC10))
{//上升沿触发中断,为释放状态
TCCR2=0x79; //8M/8=1MHz
MCUCR&=~(0x01<<ISC10);//clear ISC10 ,设为下降沿触发
BRAKE_LED_OFF;
}
else
{//下降沿触发中断,为刹车状态
TCCR2=0;//
MCUCR|=(0x01<<ISC10);//set ISC10,设为上升沿触发
BRAKE_LED_ON;
}
}
/***************************************************************************
串口接收中断程序
****************************************************************************/
void uart0_rx_isr(void)
{
//uart has received a character in UDR
UartBuf[UartBufCount]= UDR;
if(++UartBufCount>3)
{
UartBufCount=0;
PORTC ^=0x20;
//UartBuf[2]=Rev,Rev,Rev,Rev,Rev,Rev,LEFT_LED,RIGHT_LED
if( ((UartBuf[0]+UartBuf[1])==0xff)&& ((UartBuf[2]+UartBuf[3])==0xff) )
{
OCR2 = UartBuf[0];//速度控制信息
LrLedReg=UartBuf[2]&0x03;
PORTB&=~LrLedReg;//
uart0_tx(SpeedVal);
uart0_tx(0xff-SpeedVal);
uart0_tx(AdResult);//+24V
uart0_tx(0xff-AdResult);
}
}
}
/***************************************************************************
串口接收中断程序
****************************************************************************/
void uart0_tx(unsigned char tdata)
{
while(!(UCSRA & (1<<UDRE) ));
UDR = tdata;
}
/***************************************************************************
系统初始化
****************************************************************************/
void Hardware_init(void)
{
CLI();
Port_init();
uart0_init();
Timer1_init();
Timer2_init();
adc_init();
MCUCR = (0x01<<ISC01)|(0x01<<ISC11);//INT0、1下降沿触发
GICR = (0x01<<INT0)|(0x01<<INT1); //INT0、1使能
TIMSK = (0x01<<OCIE1A);
SEI();
BRAKE_LED_OFF;
}
/***************************************************************************
延时程序
****************************************************************************/
void Delay_ms(unsigned int m) //1ms延时
{
int l,j;
for(l=0;l<m;l++)
for(j=0;j<500;j++)
{
;
}
}
/**************************************************************************
主函数
**************************************************************************/
void main(void)
{
int k;
Hardware_init();
//ADCSRA |=(1<<ADSC); //启动AD转换
while(1)
{
ADCSRA |=(1<<ADSC); //启动AD转换
Delay_ms(100);
if(++k>5)
{
k=0;
PORTC ^=0x20;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -