AVRmega16通过一个定时器实现多路IO口输出多路可调的PWM
2015-11-29 23:06
393 查看
本人在做舞蹈机器人时,想到了通过一个定时器实现多路IO口输出多路可调的PWM,用于控制舞蹈机器人各部分的舵机。这个方法比较简洁而且实现自己的要求,且易于理解。
/*角度值:15度500us(10)——215度2500us(50)
端口A0——A5 B0——B5 C0——C5 */
#include<iom16v.h>
#include<macros.h>
#define uint unsigned int
#define uchar unsigned char
#define dt 70
#define sp 18
#pragma interrupt_handler timer0:10
#pragma interrupt_handler timer1:9
uint base0=0,base1=0;
uchar i,k;
uint j=0;
uchar s[18]={14,15,14,2,17,13,13,13,5,14,12,5,14,6,8,17,12,14};
uchar std[18]={14,6,14,2,14,13,13,13,5,5,12,5,14,6,10,17,12,12};
void chushi()
{
uchar i;
for(i=0;i<18;i++)
s[i]=std[i];
}
void timer_init() //中断初始化
{
TCNT1H=0XFF; //定时器1 初始化
TCNT1L=0XD2; //0.05ms定时初值,准确
TCCR1B=0X02; //8分频
TCCR0=0X02;//计数器0 8分频
TCNT0=0XD2;//计数器0 50us中断一次
TIMSK=0X05;//开启中断溢出中断0
SREG=0X80;//开启总中断
}
void main()
{
chushi();
timer_init();
}
void timer0()//每50us中断一次产生占空比可调的pwm
{
TCNT0=0XD2;//计数器0 50us中断一次
base0++;
if(base0==378)
{ base0=0;
PORTA=0xff;
PORTC=0xff;
}
for(i=0;i<12;i++)//A口 s[0]——s[5] C口 s[6]——s[11]端口输出脉冲
{
if(i<=5)
{
if(base0==s[i])
PORTA&=~BIT(i);
}
if(i>5)
{
if(base0==s[i])
{
j=i-6;
PORTC&=~BIT(j);
}
}
}
}
void timer1(void)
{
TCNT1H=0XFF;
TCNT1L=0XD2; //重装初值
base1++;
if(base1==378)
{ base1=0;
PORTB=0xff;
}
for(k=12;k<18;k++) //B 口S[12]——s[17]
{
if(base1==s[k])
{
/*角度值:15度500us(10)——215度2500us(50)
端口A0——A5 B0——B5 C0——C5 */
#include<iom16v.h>
#include<macros.h>
#define uint unsigned int
#define uchar unsigned char
#define dt 70
#define sp 18
#pragma interrupt_handler timer0:10
#pragma interrupt_handler timer1:9
uint base0=0,base1=0;
uchar i,k;
uint j=0;
uchar s[18]={14,15,14,2,17,13,13,13,5,14,12,5,14,6,8,17,12,14};
uchar std[18]={14,6,14,2,14,13,13,13,5,5,12,5,14,6,10,17,12,12};
void chushi()
{
uchar i;
for(i=0;i<18;i++)
s[i]=std[i];
}
void timer_init() //中断初始化
{
TCNT1H=0XFF; //定时器1 初始化
TCNT1L=0XD2; //0.05ms定时初值,准确
TCCR1B=0X02; //8分频
TCCR0=0X02;//计数器0 8分频
TCNT0=0XD2;//计数器0 50us中断一次
TIMSK=0X05;//开启中断溢出中断0
SREG=0X80;//开启总中断
}
void main()
{
chushi();
timer_init();
}
void timer0()//每50us中断一次产生占空比可调的pwm
{
TCNT0=0XD2;//计数器0 50us中断一次
base0++;
if(base0==378)
{ base0=0;
PORTA=0xff;
PORTC=0xff;
}
for(i=0;i<12;i++)//A口 s[0]——s[5] C口 s[6]——s[11]端口输出脉冲
{
if(i<=5)
{
if(base0==s[i])
PORTA&=~BIT(i);
}
if(i>5)
{
if(base0==s[i])
{
j=i-6;
PORTC&=~BIT(j);
}
}
}
}
void timer1(void)
{
TCNT1H=0XFF;
TCNT1L=0XD2; //重装初值
base1++;
if(base1==378)
{ base1=0;
PORTB=0xff;
}
for(k=12;k<18;k++) //B 口S[12]——s[17]
{
if(base1==s[k])
{
相关文章推荐
- 安装MySQL配置时报错的处理方法
- Android项目开发四
- 使用grep恢复被删除文件内容【转】
- 第十七天-linux系统定时任务crontab入门讲解
- 《构建之法:现代软件工程》第一章有感
- python 的类变量和对象变量
- 蓝懿 ios技术交流和心得分享 11.29
- 用c++代码实现贪心算法求解最短路径问题
- linux-文件系统管理04-文件系统
- HDU 5586 Sum
- Linux下常用命令总结
- 红黑树
- 大小写转换函数
- F5多出口配置
- Activity横竖屏切换时生命周期变化 转载
- mac osx get postgresql path
- EJB三种bean
- 堆排序/优先级队列
- HDU 5565 Clarke and baton
- log4j输出日志到flume-ng(个人记录)