⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 使用ICCAVR编辑
💻 C
字号:
//ICC-AVR application builder : 2007-5-29
// Target : M8
// Crystal: 11.059Mhz

/** MCU1的程序
 *  功能:
 *			1. 控制直流电机正、反转,停止
 *          2. 用快速PWM方式(模式14)调节电机转速
 *          3. 用串口接收MCU2传来的PWM占空比(脉宽)
 */

#include <iom8v.h>
#include <macros.h>

#define FORWARD  0x00
#define BACKWARD 0x01
#define STOP     0x02

/*
PB0------in1
PB1------in2(OC1A)
PB2------in3(OC1B)
PB3------in4
*/

//初始时向前转
unsigned char dir_flag;		// dir_flag 电机方向标记
unsigned char data=0,		// 接收字符临时存入data
			  Rec_data[10]={0};		// 接收数组
unsigned char uart_rece_flag=0;		// 接收完成标志

void port_init(void)
{
 PORTB = 0x0F;//0000 1111
 DDRB  = 0x0F;//0000 1111
 PORTC = 0x31;//0011 0001
 DDRC  = 0x31;//0011 0001
 PORTD = 0xf0;//1111 0000
 DDRD  = 0xc3;//1100 0011
}

//TIMER1 initialize - prescale:1
// WGM: 14) PWM fast, TOP=ICRn
// desired value: 20KHz
// actual value: 20.034KHz (0.2%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 
 TCNT1H = 0x00; //setup
 TCNT1L = 0x00;
 
 OCR1AH = 0x02;
 OCR1AL = 0x27;

 OCR1BH = 0x02;
 OCR1BL = 0x27;

 ICR1H  = 0x02; // 20kHz
 ICR1L  = 0x27;
 
 TCCR1A = 0x02; // OCR1A未连接,做普通端口操作
 TCCR1B = 0x19; //start Timer
}

#pragma interrupt_handler timer1_compa_isr:7
void timer1_compa_isr(void)
{
 PORTB&=~(1<<1);// 输出比较匹配时,PB0,PB1全部为低,使得运动停止
 PORTB&=~(1<<0);
}

#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
// 定时器1溢出中断处理
{
 if(dir_flag==FORWARD)
 {//如果要求电机正转
  PORTB&=~(1<<0);  // pb0=0=in1
  PORTB|=(1<<1);   // pb1=1=in2
 }
 else if(dir_flag==BACKWARD)
 {//如果要求电机反转
 PORTB&=~(1<<1);		// pb1=0
 PORTB|=(1<<0);			// pb0=1
 }
 else//如果要求电机停止
 {
 PORTB&=~(1<<1);		// pb0=0
 PORTB&=~(1<<0);		// pb1=0
 }
}

//UART0 initialize
// desired baud rate: 9600
// actual: baud rate:9600 (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 = 0x47; //set baud rate lo
 UBRRH = 0x00; //set baud rate hi
 UCSRB = 0x90;
}


#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
// 串口接收中断处理
// 记录接收到的字符,根据协议将接收到的数据存入数组Rec_data[]
{
 //uart has received a character in UDR
 static unsigned char rece_num=0;		// 接收字节数计数
 
 data=UDR;					// 接收字符临时存入data
 
 if((data==0xAA)&&(rece_num==0))//判断第0字节,0XAA起始位判断
     {
	 Rec_data[rece_num]=data;		// 根据协议,记录通信字节
     rece_num++;					// 接收字符数计数加1
     }  
 else if(rece_num>0)//第1字节到第7字节寄存到接收数据中
   {
	 Rec_data[rece_num]=data;
     rece_num++;
	 if(rece_num==8)//接收完毕,标志位置1
      {
	     rece_num=0; //准备接收下一帧字节
	     uart_rece_flag=1;
       }
    }
}

#pragma interrupt_handler int0_isr:2
void int0_isr(void)
// 外部中断0处理,电机停止
{
 //external interupt on INT0
 dir_flag=STOP;
 PORTB&=~(1<<0);		// pb0=0
 PORTB&=~(1<<1);		// pb1=0
}


//call this routine to initialize all peripheralsz
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 timer1_init();
 uart0_init();
 MCUCR = 0x0A;
 GICR  = 0x40;
 TIMSK = 0x14; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

//
void main(void)
{
  unsigned char i=0;
  init_devices();
  dir_flag=STOP;		// 初始化,电机停转
  
   while(1)
 {
		if(uart_rece_flag==1)	// 接收完成位置位后,改变PWM占空比
			{				
				i++;
				if(i<=25)		// 每接收25次改变一次PC的led7显示状态
					{
						PORTD&=~(1<<7);//接收到数后led7闪烁
					}
				else if(i<=50)
					{
						PORTD|=1<<7;//接收到数后led7闪烁
					}
				else 
					{
						i=0;
					}
  
				uart_rece_flag=0;		// 串口接收完成位清0

				 if(Rec_data[1]==0)		// Rec_data[1]=pwmtemph
					 {		// 占空比快为0时,停止电机
						 if(Rec_data[2]<=0x05)	// Rec_data[2]=pwmtempl
							  {
									dir_flag=STOP;
								}
					 }
				  else if(!(Rec_data[1]&(1<<7))) //pwmtemph最高位为电机方向位
						{
							dir_flag=FORWARD;//如果最高位为0,则为正向
						}
					else  
						{
							dir_flag=BACKWARD;
							Rec_data[1]-=1<<7;		// pwmtemph最高位清0,电机反向
						}
					
				// 改变输出比较寄存器OCR1A,改变占空比
				OCR1AH=Rec_data[1];
				OCR1AL=Rec_data[2];

			} // end if
	}		// end while
}		// end main

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -