控制AVR单片机5路PWM波形

现开发了单片机控制5路PWM波形,也可以同时控制15路直流三色灯板,按触摸屏顺序点亮的电路和程序,供大家参考。

电路为

单片机ATMEGA128控制5路PWM方波,按照74HC08逻辑编码输出15路PWM信号,一次按照迪文触摸屏点亮3种颜色灯板的5路发光信号。ULN2003提供12V电压。每个灯板通过一个CMOS管IR3205输出功率。一个74HC08通过一路PWM,这路PWM通过74HC08控制的继电器控制IR3205的开关,进而控制24V,13V,36V灯板的开关,灯板的亮度通过PWM波形的占空比调节电路的PCB如下

上面是单片机PCB,它和灯板PCB通过排线连接

图片

图片

图片

上面是灯板PCB。下面是单片机程序,程序用ICC-AVR开发,链接:https://pan.baidu.com/s/1X_7zIHR4K1ipaGRTviVtUw ;

提取码:so7m

复制这段内容后打开百度网盘手机App,操作更方便哦

//ICC-AVR application builder : 2010-6-22 15:14:03

// Target : M64A

// Crystal: 4.0000Mhz

/*

修改宏定义以实现不同功能,

*/

#include "main.h"

/*******************************************

向串口1发送单个数据,查询方式

*******************************************/

void TxUart1(unsigned char i)

{

//CLI(); //disable all interrupts

//DelayMs(1);

while (!(UCSR0A & (1<<UDRE0))); /* 等待发送缓冲器为空*/

UDR0 = i;                                         /* 发送数据*/

//SEI(); //re-enable interrupts

}

/*******************************************

向串口0发送数组,查询方式

参数1:数组指针;

参数2:数组长度;

*******************************************/

void TxArrayUart1(unsigned char *ptr,unsigned char number)

{

//CLI(); //disable all interrupts

uchar i;

for(i = 0; i < number; i++)

{

TxUart1(ptr[i]);

}

//SEI(); //re-enable interrupts

}

/*******************************************

向串口1发送单个数据,查询方式

*******************************************

void TxUart1(unsigned char i)

{

//CLI(); //disable all interrupts

while (!(UCSR1A & (1<<UDRE1))); //等待发送缓冲器为空

UDR1 = i;                                         //发送数据

//SEI(); //re-enable interrupts

}

/*******************************************

向串口0发送数组,查询方式

参数1:数组指针;

参数2:数组长度;

*******************************************

void TxArrayUart1(unsigned char *ptr,unsigned char number)

{

//CLI(); //disable all interrupts

uchar i;

for(i = 0; i < number; i++)

{

TxUart1(ptr[i]);

}

//SEI(); //re-enable interrupts

}

/*******************************************

数据接收,等待查询方式

*******************************************/

unsigned char uart_receive1(void)

{

while (!(UCSR1A & (1<<RXC1))); /* 等待接收数据*/

return UDR1; /* 获取并返回数据*/

}

//UART0 initialize

// desired baud rate: 9600

// actual: baud rate: 9615 (0.2%)

// char size: 8 bit

// parity: Disabled

void uart0_init(void)

{

UCSR0B = 0x00; //disable while setting baud rate

UCSR0A = 0x00;

UCSR0C = 0x06;

UBRR0L = 0x0C; //set baud rate lo

UBRR0H = 0x00; //set baud rate hi

UCSR0B = 0x98;

}

#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC

void uart0_rx_isr(void)

{

//uart has received a character in UDR

uart1_data = UDR0;

switch (uart1_counter)

{

case 0:

if (uart1_data == 0xaa)

uart1_counter ++;

else

uart1_counter = 0;

break;

case 1:

if ((uart1_data == 0x78) || (uart1_data == 0x79))

uart1_counter ++;

else

uart1_counter = 0;

button_type = uart1_data;

break;

case 2:

if (uart1_data == 0x00)

{

uart1_counter ++;

}

else

uart1_counter = 0;

break;

case 3:

uart1_counter ++;

button = uart1_data;

break;

case 4:

if (uart1_data == 0xcc)

uart1_counter ++;

else

uart1_counter = 0;

break;

case 5:

if (uart1_data == 0x33)

uart1_counter ++;

else

uart1_counter = 0;

break;

case 6:

if (uart1_data == 0xc3)

uart1_counter ++;

else

uart1_counter = 0;

break;

case 7:

uart1_counter = 0;

if (uart1_data == 0x3c)

{

switch(button)

{

case 0x57:

case 0x58:

case 0x63:

if(button_time == 0)

{

button_flag = 1;

button_time = 110;

}

break;

default:

if((button_time == 0) && (button_type == 0x78))

{

button_flag = 1;

}

break;

}

}

break;

default:

uart1_counter = 0;

break;

}

}

/*

#pragma interrupt_handler uart1_rx_isr:iv_USART1_RXC

void uart1_rx_isr(void)

{

//uart has received a character in UDR

uart1_data = UDR1;

switch (uart1_counter)

{

case 0:

if (uart1_data == 0xaa)

uart1_counter ++;

else

uart1_counter = 0;

break;

case 1:

if ((uart1_data == 0x78) || (uart1_data == 0x9b))

uart1_counter ++;

else

uart1_counter = 0;

break;

case 2:

if ((uart1_data == 0x00) || (uart1_data == 0x5a))

{

uart1_counter ++;

if(uart1_data == 0x5a)

time_get = 1;

}

else

uart1_counter = 0;

break;

case 3:

if(time_get)

{

time[time_get - 1] = uart1_data;

if(time_get < 6)

time_get ++;

else

{

//time_get = 0;

uart1_counter ++;

}

}

else

{

uart1_counter ++;

button = uart1_data;

}

break;

case 4:

if (uart1_data == 0xcc)

uart1_counter ++;

else

uart1_counter = 0;

break;

case 5:

if (uart1_data == 0x33)

uart1_counter ++;

else

uart1_counter = 0;

break;

case 6:

if (uart1_data == 0xc3)

uart1_counter ++;

else

uart1_counter = 0;

break;

case 7:

uart1_counter = 0;

if (uart1_data == 0x3c)

{

if(time_get)

{

time_get = 0;

time_flag = 1;

}

else

button_flag = 1;

}

break;

default:

uart1_counter = 0;

break;

}

}*/

//UART1 initialize

// desired baud rate:19200

// actual baud rate:19231 (0.2%)

// char size: 8 bit

// parity: Disabled

void uart1_init(void)

{

UCSR1B = 0x00; //disable while setting baud rate

UCSR1A = 0x00;

UCSR1C = 0x06;

UBRR1L = 0x0C; //set baud rate lo

UBRR1H = 0x00; //set baud rate hi

UCSR1B = 0x98;

}

//TIMER0 initialize - prescale:32

// WGM: Normal

// desired value: 1KHz

// actual value:  1.000KHz (0.0%)

void timer0_init(void)

{

TCCR0 = 0x00; //stop

ASSR  = 0x00; //set async mode

TCNT0 = 0x83; //set count

OCR0  = 0x7D;

// TCCR0 = 0x03; //start timer

}

#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF

void timer0_ovf_isr(void)

{

TCNT0 = 0x83; //reload counter value

if(ms)

ms--;

}

//TIMER1 initialize - prescale:64

// WGM: 0) Normal, TOP=0xFFFF

// desired value: 1KHz

// actual value:  1.008KHz (0.8%)

void timer1_init(void)

{

TCCR1B = 0x00; //stop

TCNT1H = 0xFF; //setup

TCNT1L = 0xC2;

OCR1AH = 0x00;

OCR1AL = 0x3E;

OCR1BH = 0x00;

OCR1BL = 0x3E;

OCR1CH = 0x00;

OCR1CL = 0x3E;

ICR1H  = 0x00;

ICR1L  = 0x3E;

TCCR1A = 0x00;

TCCR1B = 0x03; //start Timer

}

#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF

void timer1_ovf_isr(void)

{

//TIMER1 has overflowed

TCNT1H = 0xFF; //reload counter high value

TCNT1L = 0xC2; //reload counter low value

if(laser_ms)

laser_ms --;

if(button_time)

button_time --;

if(rf_out_time)

{

rf_out_time --;

if(RF_TYPE)

RFRUN_L;

else

RFCTL_L;

}

else

{

//if(RF_TYPE)

RFRUN_H;

//else

RFCTL_H;

}

cold_count = (cold_count < 3) ? (cold_count + 1) : 0;

if(cold_count < cold_max)

COLD_L;

else

COLD_H;

}

//TIMER2 initialize - prescale:1024

// WGM: Normal

// desired value: 20Hz

// actual value: 20.032Hz (0.2%)

void timer2_init(void)

{

TCCR2 = 0x00; //stop

TCNT2 = 0x3D; //setup

OCR2  = 0xC3;

TCCR2 = 0x05; //start

}

#pragma interrupt_handler timer2_ovf_isr:iv_TIM2_OVF

void timer2_ovf_isr(void)

{

TCNT2 = 0x3D; //reload counter value

WDR ();

if(ad_time < 20)

{

ad_time++;

}

else

{

ad_time = 0;

if(miniter == 60)

{

miniter = 0;

total_time ++;

EEPROM_write(0x110,total_time>>16);

EEPROM_write(0x111,(unsigned char)total_time>>8);

EEPROM_write(0x112,(unsigned char)total_time);

}

else

miniter ++;

if(lamp_ok)

{

if(miniter_rdy == 60)

{

miniter_rdy = 0;

total_time ++;

EEPROM_write(0x113,total_time_rdy >> 16);

EEPROM_write(0x114,(unsigned char)total_time_rdy >> 8);

EEPROM_write(0x115,(unsigned char)total_time_rdy);

}

else

miniter_rdy ++;

}

/*每一秒启动一次温度采集*/

ADCSRA = 0xcf;

}

if(beep_time)

{

beep_time--;

BEEP_L;

}

else

BEEP_H;

}

//Watchdog initialize

// prescale: 512K

void watchdog_init(void)

{

WDR (); //this prevents a timeout on enabling

WDTCR |= (1<<WDCE) | (1<<WDE);/* 30-Oct-2006 Umesh*/

WDTCR = 0x0D; //WATCHDOG ENABLED - dont forget to issue WDRs

}

void port_init(void)

{

PORTA = 0xFF;

DDRA  = 0xFF;

PORTB = 0xFF;

DDRB  = 0xFF;

PORTC = 0x0E; //m103 output only

DDRC  = 0x0F;

PORTD = 0x00;

DDRD  = 0x93;

PORTE = 0x00;

DDRE  = 0x00;

PORTF = 0x01;

DDRF  = 0x01;

PORTG = 0x00;

DDRG  = 0x13;

}

#pragma interrupt_handler int0_isr:iv_INT0

void int0_isr(void)

{

//external interupt on INT0

}

//ADC initialize

// Conversion time: 16uS

void adc_init(void)

{

ADCSRA = 0x00; //disable adc

ADMUX = 0xc1; //select adc input 1

ACSR  = 0x80;

ADCSRA = 0xcf;//|| 0x40;

}

#pragma interrupt_handler adc_isr:iv_ADC

void adc_isr(void)

{

//conversion complete, read value (int) using...

ad_value=ADCL;            //Read 8 low bits first (important)

ad_value|=(int)ADCH << 8; //read 2 high bits and shift into top byte

temp_flag = 1;

}

//call this routine to initialize all peripherals

void init_devices(void)

{

//stop errant interrupts until set up

CLI(); //disable all interrupts

XDIV  = 0x00; //xtal divider

XMCRA = 0x00; //external memory

port_init();

//watchdog_init();

//adc_init();

//timer0_init();

//timer1_init();

//timer2_init();

uart0_init();

uart1_init();

MCUCR = 0x00;

EICRA = 0x00; //extended ext ints

EICRB = 0x00; //extended ext ints

EIMSK = 0x00;

TIMSK = 0x45; //timer interrupt sources

ETIMSK = 0x00; //extended timer interrupt sources

SEI(); //re-enable interrupts

//all peripherals are now initialized

}

/************************************************

发送需要显示的字符/坐标到液晶控制器;

参数1:坐标X;

参数2:坐标Y;

参数3:字符串数组;

************************************************/

void DisString(unsigned short x,unsigned short y,unsigned int word_color,unsigned int ground_color,unsigned char big,char * string)

{

unsigned char i = 0;

SetColor(word_color,ground_color);

//AA 55 00 00 00 00 49 CC 33 C3 3C

TxUart1(0xaa);

if(big)

TxUart1(0x55);

else

TxUart1(0x6f);

TxUart1( (uchar)((x*EIGHT_SWITCH) >> 8) );

TxUart1( (uchar)(x*EIGHT_SWITCH) );

TxUart1( (uchar)((y*EIGHT_SWITCH) >> 8) );

TxUart1( (uchar)(y*EIGHT_SWITCH) );

while(string[i] != 0)

{

TxUart1(string[i]);

i++;

}

TxUart1(0xcc);

TxUart1(0x33);

TxUart1(0xc3);

TxUart1(0x3c);

}

原文地址:https://www.cnblogs.com/zgdcnyhl/p/12344381.html

时间: 2024-07-31 10:24:44

控制AVR单片机5路PWM波形的相关文章

AVR单片机教程——PWM调光

PWM 两位数码管的驱动方式是动态扫描,每一位都只有50%的时间是亮的,我们称这个数值为其占空比.让引脚输出高电平点亮LED,占空比就是100%. 在驱动数码管时,我们迫不得已使占空比为50%,因为不能让两位真正同时地显示不同的数字.但是,我们也可以有意地让LED的占空比不到100%,以降低其亮度. 占空比是可以用程序来调节的.下面的程序允许用户用按键调整蓝色LED的占空比,并通过数码管来显示. #include <ee1/ee.h> #define DUTY_MAX 9 int main()

单片机成长之路(avr基础篇)- 003 AVR单片机的BOOT区

BOOT区的由来基于一个简单的道理,即单片机的程序是保存在FLASH中的,要运行程序就必须不停的访问FLASH存储器.对于一般的FLASH存储器,数据的写入需要一定的时间来完成,在数据写入完成之前,存储器中所有的数据都是不可读的,这就在运行旧程序和写入新程序之间造成了一个矛盾. 使用BOOT区是解决这个矛盾的方法之一,它将FLASH存储器从物理上分为两个独立的区域,对其中的一个区的数据写入不会影响到另一个区的数据读取操作.我们可以让单片机的程序在其中一个区(通常是BOOT区)运行,而运行着的程序

Arduino控制16路PWM舵机驱动板(PCA9685)

最近买了块16路PWM舵机驱动板,测试后做个总结. 舵机原理网上资料很多就不详细介绍了,一般以9g舵机为例,一个20ms的周期内通过0.5ms到2.5ms的脉冲宽度控制舵机角度. 板子为16通道12bit PWM舵机驱动,用2个引脚通过I2C就可以驱动16个舵机. 修改例子为可以通过串口设置舵机角度 1 #include <Wire.h> 2 #include <Adafruit_PWMServoDriver.h> 3 4 //默认地址 0x40 5 Adafruit_PWMSer

AVR单片机教程——EasyElectronics Library v2.0手册

本文隶属于AVR单片机教程系列. ? adc.h bit.h button.h buzzer.h dac.h delay.h ee.h exin.h exout.h lcd.h ldr.h led.h pin.h pot.h print.h pwm.h rgbw.h rotary.h segment.h switch.h timer.h tone.h uart.h wave.h ? 主要更新: 由于修改了一些接口,与之前版本不完全兼容,主版本号更新为2: 正式支持中断,初步使用回调: UART支

【007】AVR单片机中断系统

AVR单片机的21个中断源 I/O端口的第二功能 AVR单片机共有单个定时器,定时/计数器1是16bit的,其余的定时/计数器0和定时/计数器2都是8bit的定时器. 定时器的工作模式 普通模式 CTC模式 快速PWM模式 相位修正PWM模式 相位频率修正PWM模式 输入捕获模式 和51单片机的定时计数器类似,根据设定的时钟频率,每过一个时钟,计数寄存器数值加1. 用到的寄存器 T/C1控制寄存器B:(控制时钟的来源和频率) 后三位的设置,1表示定时器停止,2~6表示不同频率的内部时钟,7~8表

一种具有12路PWM直流电机的串口遥控机器人

技术领域本实用新型涉及一种一种具有12路PWM直流电机的串口遥控机器人,尤其是一种可以用串口无线WIFI遥控的智能机器人.背景技术现有常规遥控机人按照无线电信号的遥控进行动作,也可以按照存储在寄存器里面的程序动作,但是动作电机较少,一般只有4路PWM直流电机,这对机器人的行动带来很大的不便.一种具有12路PWM直流电机的串口遥控机器人是一种具有12路PWM直流电机的机器人,操作者可以使用计算机串口WIFI信号对它的12路直流电机进行遥控,它也可以按照其控制电路中的24C04铁电存储器里面的数据,

混杂设备驱动--输出两路PWM

尝试用2440的TOUT0和TOUT1输出PWM驱动两个电机,电机的硬件驱动电路是使用L298N. 先单独测试TOUT0的PWM输出: (1)驱动程序:使用misc混杂设备驱动模型,当然也可以使用基本的字符设备模型. 使用misc设备驱动模型步骤: ①初始化一个struct miscdevice结构体:主要是file_operation结构体成员和name ②使用misc_register和misc_deregister注册和注销这个结构体 代码示例: #include <linux/modul

avr频率占空比可调波形输出子函数

#ifndef _KPWM_H_ #define _KPWM_H_ /*************avr频率占空比可调波形输出子函数**************/ ////作者:王泡泡 ///形参:Fclk赋值设定频率(单位为k)  范围:  1K 到 256K ///      rat设定占空比(单位为百分比)eg:40 则输出方波占空比为百分之四十 //频率误差小于2%,占空比误差小于5% //PWM频率计算公式为f=fox/N(1+TOP) fox为晶振频率 N为分频系数 TOP为计数计数最

nRF51822使用Timer制作4路PWM波详解

Date:2015.5.8 Author:杨正  QQ:1209758756 <[email protected]> 一.            pwm简介 PWM英文名叫Pulse Width Modulation,中文名叫脉宽调制.那它到底是什么呢?其实它是由定时器产生的,比普通的定时器多了一个比较寄存器.PWM里面有一个词叫占空比,即一个周期内,高电平持续时间与周期的比值.如下图: 占空比(dutycycle) = t/T. PWM用途:控制电机调速,控制蜂鸣器播放音乐,控制led灯亮度