I am a beginner in AVR and don't have any specific practical topics. I disassembled a few small motors and learned a lot while playing with them. I hope this can help beginners.
This small DC motor control system is easy to implement. It uses PWM speed regulation. The drive circuit can be built with discrete components (there are many such circuits on the Internet) or integrated IC devices. I use L293. The circuit is very simple, so I won't draw a picture. The
wiring description is as follows:
PORTC7, PORTC6 are connected to L293 IN1, IN2 respectively. According to the L293 data, ENA=H, IN1=H, IN2=L Forward
ENA=H, IN1=L, IN2=H Reverse
ENA=H, same as IN2 (IN4), same as IN1 (IN3) Quick stop
ENA=L, stop
OCR2 connected to L293 ENA
speed measurement feedback signal connected to T0
Code description is as follows:
This system can receive host computer control commands through the serial port, and can realize start, stop, speed regulation, and timely speed feedback. The serial port adopts the receiving interrupt mode, and the command protocol is as follows: the command adopts the M**C mode, and all command strings start with M and end with C. The definition of the two characters in the middle: s means speed regulation, and the ratio of the third command character and 0xff is used as the duty cycle of PWM for speed regulation.
d means sending the current speed to the upper computer.
t means stop,
r means start,
and o means direction reversal .
The speed measurement uses the speed measurement pulse signal (Hall speed sensor) as the external counting pulse of T2, T1 CTC mode, to achieve 1s timing, compare match interrupt is allowed, and the interrupt service program reads the value of TCNT2, which is the speed. After reading, Timer2 is reinitialized.
For beginners, the speed measurement can be tested with the CPU fan. The CPU fan comes with a speed output line, and the internal Hall sensor is used. Note that the output end of the Hall sensor is an OC gate open circuit, and a pull-up resistor needs to be connected. You can get a very standard square wave! In addition: pay attention to connecting the fan ground and your development board ground together.
The original code is as follows:
The program uses ICC to automatically generate code, and then ported to codevision. I think the ICC automatically generated code has a clear structure and is very suitable for beginners, but there may be some inappropriate places!
// Target : M16
// Crystal: 4.0000Mhz
#include
#include
#include
unsigned char rx_data[5];//Data buffer
volatile unsigned char rx_counter=0;
volatile unsigned char crut_sped;//Current speed
//const unsigned char seg_table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
//0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0b01000000; //m103 output only
DDRC = 0xFF;
PORTD = 0xFF;
DDRD = 0xFF;
}
//External event count
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x00;
OCR0 = 0x00;
TCCR0 = 0x07; //start
}
//TIMER1 initialize - prescale:64
// WGM: 4) CTC, TOP=OCRnA
// desired value: 1Sec
// actual value: 1.000Sec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0x0B; //setup
TCNT1L = 0xDD;
OCR1AH = 0xF4;
OCR1AL = 0x23;
OCR1BH = 0xF4;
OCR1BL = 0x23;
ICR1H = 0xF4;
ICR1L = 0x23;
TCCR1A = 0b00000000;
TCCR1B = 0b00001011; //start Timer
}
//TIMER2 initialize - prescale:64
// WGM: PWM Phase correct
// desired value: 122Hz
// actual value: 122.549Hz (0.4%)
void timer2_init(void)
{
TCCR2 = 0x00; //stop
TCNT2 = 0x01; //set count
OCR2 = 0x3f; //set compare
TCCR2 = 0b01100011; //start timer
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
//compare occured TCNT3=OCR3A
crut_sped=TCNT0;
timer0_init();
}
//UART0 initialize
// desired baud rate: 19200
// actual: baud rate:19231 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = 0x06;
UBRRL = 0x0C; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
interrupt[USART_RXC] void uart_rx_isr(void)
{
/*if (rx_counter >= 4)
{
rx_counter = 0;
if ((!(rx_data[0] == 'M'))||(!(rx_data[3] == 'C')))
{
rx_data[0]=0;
rx_data[1]=0;
rx_data[2]=0;
rx_data[3]=0;
}
} */
rx_data[rx_counter] = UDR;
if (rx_data[rx_counter]=='M')
{
rx_data[0]=rx_data[rx_counter];
rx_counter=0;
}
rx_counter++;
}
void init_devices(void)
{
//stop errant interrupts until set up
#asm("cli"); //disable all interrupts
port_init();
timer0_init();
timer1_init();
timer2_init();
uart_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0b00010000; //输出比较匹配A中断使能
#asm("sei");//re-enable interrupts
//all peripherals are now initialized
}
void timer2_reset(unsigned char i)
{
if((i>0x00)&&(i<0xff))
{
TCCR2 = 0x00; //stop
TCNT2 = 0x01; //set count
OCR2 = i; //set compare
TCCR2 = 0b01100011; //start timer
}
}
void speed_direction(void)
{
PORTC^=0x80;
PORTC^=0x40;
}
void main(void)
{
init_devices();
while(1)
{
if (rx_counter==4)
{
rx_counter=0;
if ((rx_data[0] == 'M')&&(rx_data[3] == 'C'))
{
if(rx_data[1]=='s')//设定速度
{
timer2_reset(rx_data[2]);
}
else if(rx_data[1]=='d')
{
putchar(crut_sped);
}
else if(rx_data[1]=='t')
{
PORTC=0x00;
}
else if(rx_data[1]=='r')
{
PORTC=0x80;
}
else if(rx_data[1]=='o')
{
speed_direction();
}
}
else
{
printf("your command is wrong
");
}
rx_data[0]=0;
rx_data[1]=0;
rx_data[2]=0;
rx_data[3]=0;
}
}
}
Reference address:Small DC Motor Control Example
This small DC motor control system is easy to implement. It uses PWM speed regulation. The drive circuit can be built with discrete components (there are many such circuits on the Internet) or integrated IC devices. I use L293. The circuit is very simple, so I won't draw a picture. The
wiring description is as follows:
PORTC7, PORTC6 are connected to L293 IN1, IN2 respectively. According to the L293 data, ENA=H, IN1=H, IN2=L Forward
ENA=H, IN1=L, IN2=H Reverse
ENA=H, same as IN2 (IN4), same as IN1 (IN3) Quick stop
ENA=L, stop
OCR2 connected to L293 ENA
speed measurement feedback signal connected to T0
Code description is as follows:
This system can receive host computer control commands through the serial port, and can realize start, stop, speed regulation, and timely speed feedback. The serial port adopts the receiving interrupt mode, and the command protocol is as follows: the command adopts the M**C mode, and all command strings start with M and end with C. The definition of the two characters in the middle: s means speed regulation, and the ratio of the third command character and 0xff is used as the duty cycle of PWM for speed regulation.
d means sending the current speed to the upper computer.
t means stop,
r means start,
and o means direction reversal .
The speed measurement uses the speed measurement pulse signal (Hall speed sensor) as the external counting pulse of T2, T1 CTC mode, to achieve 1s timing, compare match interrupt is allowed, and the interrupt service program reads the value of TCNT2, which is the speed. After reading, Timer2 is reinitialized.
For beginners, the speed measurement can be tested with the CPU fan. The CPU fan comes with a speed output line, and the internal Hall sensor is used. Note that the output end of the Hall sensor is an OC gate open circuit, and a pull-up resistor needs to be connected. You can get a very standard square wave! In addition: pay attention to connecting the fan ground and your development board ground together.
The original code is as follows:
The program uses ICC to automatically generate code, and then ported to codevision. I think the ICC automatically generated code has a clear structure and is very suitable for beginners, but there may be some inappropriate places!
// Target : M16
// Crystal: 4.0000Mhz
#include
#include
#include
unsigned char rx_data[5];//Data buffer
volatile unsigned char rx_counter=0;
volatile unsigned char crut_sped;//Current speed
//const unsigned char seg_table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
//0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0b01000000; //m103 output only
DDRC = 0xFF;
PORTD = 0xFF;
DDRD = 0xFF;
}
//External event count
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x00;
OCR0 = 0x00;
TCCR0 = 0x07; //start
}
//TIMER1 initialize - prescale:64
// WGM: 4) CTC, TOP=OCRnA
// desired value: 1Sec
// actual value: 1.000Sec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0x0B; //setup
TCNT1L = 0xDD;
OCR1AH = 0xF4;
OCR1AL = 0x23;
OCR1BH = 0xF4;
OCR1BL = 0x23;
ICR1H = 0xF4;
ICR1L = 0x23;
TCCR1A = 0b00000000;
TCCR1B = 0b00001011; //start Timer
}
//TIMER2 initialize - prescale:64
// WGM: PWM Phase correct
// desired value: 122Hz
// actual value: 122.549Hz (0.4%)
void timer2_init(void)
{
TCCR2 = 0x00; //stop
TCNT2 = 0x01; //set count
OCR2 = 0x3f; //set compare
TCCR2 = 0b01100011; //start timer
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
//compare occured TCNT3=OCR3A
crut_sped=TCNT0;
timer0_init();
}
//UART0 initialize
// desired baud rate: 19200
// actual: baud rate:19231 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = 0x06;
UBRRL = 0x0C; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
interrupt[USART_RXC] void uart_rx_isr(void)
{
/*if (rx_counter >= 4)
{
rx_counter = 0;
if ((!(rx_data[0] == 'M'))||(!(rx_data[3] == 'C')))
{
rx_data[0]=0;
rx_data[1]=0;
rx_data[2]=0;
rx_data[3]=0;
}
} */
rx_data[rx_counter] = UDR;
if (rx_data[rx_counter]=='M')
{
rx_data[0]=rx_data[rx_counter];
rx_counter=0;
}
rx_counter++;
}
void init_devices(void)
{
//stop errant interrupts until set up
#asm("cli"); //disable all interrupts
port_init();
timer0_init();
timer1_init();
timer2_init();
uart_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0b00010000; //输出比较匹配A中断使能
#asm("sei");//re-enable interrupts
//all peripherals are now initialized
}
void timer2_reset(unsigned char i)
{
if((i>0x00)&&(i<0xff))
{
TCCR2 = 0x00; //stop
TCNT2 = 0x01; //set count
OCR2 = i; //set compare
TCCR2 = 0b01100011; //start timer
}
}
void speed_direction(void)
{
PORTC^=0x80;
PORTC^=0x40;
}
void main(void)
{
init_devices();
while(1)
{
if (rx_counter==4)
{
rx_counter=0;
if ((rx_data[0] == 'M')&&(rx_data[3] == 'C'))
{
if(rx_data[1]=='s')//设定速度
{
timer2_reset(rx_data[2]);
}
else if(rx_data[1]=='d')
{
putchar(crut_sped);
}
else if(rx_data[1]=='t')
{
PORTC=0x00;
}
else if(rx_data[1]=='r')
{
PORTC=0x80;
}
else if(rx_data[1]=='o')
{
speed_direction();
}
}
else
{
printf("your command is wrong
");
}
rx_data[0]=0;
rx_data[1]=0;
rx_data[2]=0;
rx_data[3]=0;
}
}
}
Previous article:Transplant ICCAVR to WINAVR to play the first song (music.c)
Next article:18B20 program under M8-ICCAVR
- Popular Resources
- Popular amplifiers
Recommended Content
Latest Microcontroller Articles
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
MoreDaily News
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
Guess you like
- TI - Delivering Ultra-High Power Density for 100W USB Power Delivery Adapters
- What challenges does the epidemic bring to engineers?
- Seeking routines for driving LPS33HW pressure sensor of STM32F103 series
- Just to tell you a joke, I spent the whole afternoon trying to write a for loop properly.
- Three solutions for implementing motor control design, which one is better?
- 【GD32307E-START】+Serial communication function test
- The software engineer said he doesn't know how to use GPIO to simulate I2C. Is he a newbie?
- 04. Anlu SparkRoad domestic FPGA evaluation [Learning] Digital tube display
- Download TE's latest trend report "Antenna Considerations When Designing Wireless Communication Systems" and answer questions to win prizes!
- L3 value range