AVR的型号是ATmega88,51的型号是stc12c5410ad。
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include <inttypes.h>
#include <avr/sleep.h>
#include <compat/ina90.h>
#define SERVO_T 20000
volatile uint16_t data[9];
volatile uint8_t channel_count;
void IO_Init() {
// OCR1A输出
DDRB |= _BV(PB1);
PORTB &= ~_BV(PB1);
// 输出一个舵机周期分割信号
DDRD |= _BV(PD0);
}
void T1_Init() {
TCCR1B = 0x00;
ICR1 = data[0]; // CH1值
OCR1A = data[0] - 400; // 尾部有400us结束标记
TCCR1C = 0x00;
TCCR1A = _BV(COM1A1) | _BV(WGM11); // 比较匹配时输出底电平
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11);
// 打开定时器溢出中断
TIMSK1 = _BV(OCIE1A) | _BV(TOIE1);
_delay_ms(1);
OCR1A = data[1] - 400; // 设定CH2值
}
uint8_t read_Osccal() {
uint8_t res;
uint8_t mode[3];
uint8_t i;
res = 0;
// 读取三个备份,进行比较,若只有两个相同,则将不同的备份重新写为相同,保持三个备份一致
for (i = 0; i < 3; i++){
eeprom_busy_wait();
mode[i] = eeprom_read_byte((uint8_t*)(i));
}
_delay_ms(10);
if (mode[0] == mode[1]) {
res = mode[0];
if (mode[2] != res) {
eeprom_busy_wait();
eeprom_write_byte((uint8_t*)(2), res);
}
} else {
if (mode[0] == mode[2]) {
res = mode[0];
_delay_ms(10);
eeprom_busy_wait();
eeprom_write_byte((uint8_t*)(1), res);
} else
if (mode[1] == mode[2]) {
res = mode[1];
_delay_ms(10);
eeprom_busy_wait();
eeprom_write_byte((uint8_t*)(0), res);
}
}
return res;
}
SIGNAL(SIG_OVERFLOW1){
volatile uint8_t next_channel;
channel_count ++;
if (channel_count == 9) channel_count = 0;
ICR1 = data[channel_count]; // 设定当前通道值
next_channel = channel_count + 1;
if (next_channel == 9) next_channel = 0;
OCR1A = data[next_channel] - 400; // 下一个通道正脉宽
// 产生一个PPM周期的标记信号
PORTD &= ~_BV(PD0);
}
SIGNAL(SIG_OUTPUT_COMPARE1A) {
if (channel_count == 8) {
// 产生一个PPM周期的标记信号
_delay_us(2);
PORTD |= _BV(PD0);
}
}
int main(){
cli();
// 关闭模拟比较器
ACSR |= _BV(ACD);
// 禁止开门狗
wdt_disable();
// 初始化输入输出口
IO_Init();
// 校正主频
eeprom_busy_wait();
OSCCAL = read_Osccal();
data[0] = 1520; // CH1, 1.52ms中立点
data[1] = 1520; // CH2, 1.52ms中立点
data[2] = 1000; // CH3, 1ms最低点(油门通道)
data[3] = 1520; // CH4, 1.52ms中立点
data[4] = 1520; // CH5, 1.52ms中立点
data[5] = 1520; // CH6, 1.52ms中立点
data[6] = 1520; // CH7, 1.52ms中立点
data[7] = 1520; // CH8, 1.52ms中立点
// 帧同步
data[8] = SERVO_T - data[0] - data[1] - data[2] - data [3] - data[4] - data[5] - data[6] - data[7];
channel_count = 0;
// 产生一个PPM周期的标记信号
PORTD |= _BV(PD0);
_delay_us(2);
T1_Init();
sei();
while(1) {
};
}
这是一个用hc164将1路pwm分成8路的程序,能不能给详细注释一下或者说一下具体的算法,我刚学51,avr的程序看不懂~
回复1:C语言通用,但是端口定义,定时器,中断都不一样,看不懂avr的~
回复2:需要改端口,头文件,定时器,中断,但是我不会改,请帮忙改一下,用哪个端口可以随便改,51的我能看懂。
回复3:AVR程序只是关闭了“看门狗,eeprom”吧,stc12c5410有PWM功能~
求助,将AVR单片机程序转为51单片机的
答案:4 悬赏:0 手机版
解决时间 2021-02-12 06:28
- 提问者网友:温旧梦泪无声
- 2021-02-12 03:12
最佳答案
- 五星知识达人网友:不如潦草
- 2021-02-12 04:18
首先#include <inttypes.h>这个文件你能找到的话基本就没什么问题了。
其中关键的一个宏_BV(i)1左移i位的意思。比如,_BV(PD0)就是左移0位,就是0x01了,PORTD &= ~_BV(PD0);就是PD&=~0x01;意思就是PORTD第0位清0.PORTD |= _BV(PD0);就是PORTD第零位置1了。这个是可移植的,直接把PORTD改成P1,P2都行。关键是这个宏。应该是这样定义的
#define _BV(i) ((1<<i))//这就是一个可变的mask
OSCCAL = read_Osccal();这个你改不了了,51的频率不能由程序控制
其中关键的一个宏_BV(i)1左移i位的意思。比如,_BV(PD0)就是左移0位,就是0x01了,PORTD &= ~_BV(PD0);就是PD&=~0x01;意思就是PORTD第0位清0.PORTD |= _BV(PD0);就是PORTD第零位置1了。这个是可移植的,直接把PORTD改成P1,P2都行。关键是这个宏。应该是这样定义的
#define _BV(i) ((1<<i))//这就是一个可变的mask
OSCCAL = read_Osccal();这个你改不了了,51的频率不能由程序控制
全部回答
- 1楼网友:蓝房子
- 2021-02-12 05:59
arm7,9是32位mcu,avr\51是8位mcu,32位机可以运算非常复杂的指令,进行大量的数据计算,比如视频数据,能力较8位机强很多。运算速度也高好多倍. avr与51相比采用精简指令集(51是复杂指令集),可以在每个时钟周期内执行一条命令,而51至少需要12个时钟周期,avr的运算能力比51强很多。另外, 像atmega8之类的单片机都自带ad转换器,应用起来很方便,单片机本身成本也不高. 缺点:arm7,9要掌握有难度,现在很多大学所谓的嵌入式,仅仅是半只脚走路,只教一些简单的程序设计,遇到实际问题时的处理手法教授很少。而更要紧的是,arm7,9系统还包括硬件电路,这里面涉及高速电路设计内容,不是初学者能轻易掌握的。 avr的编程一般需要gcc或者icc,有特定的环境,与51相比,稍微复杂一点,资料也没有51多,最好是先有51基础后再学,但它的运算能力很强,在实际生产中也用得很多,推荐给那些有51基础,愿意从事智能控制方面的朋友使用。 51是基础,电路简单,编程也比较容易,资料众多,芯片很便宜,也很容易买到,适合入门级,但一旦数据量很大,涉及复杂运动控制,视频等内容时,51就力不从心了.运算的速度和效率低也是51的一个缺点.
简单的总结下就是avr的指令系统比较精简,总线结构也与51不同,因此速度比51更快。其次,如果说性能的话,至少arm更优。因为arm是32位处理器,频率可达百兆赫兹,速度和处理能力远远优于avr和51。
- 2楼网友:拾荒鲤
- 2021-02-12 05:42
你需要改端口啊,用哪个IO口都不知道怎么改呢,还有就是头文件如果需要的话也要改的,C本身是不需要改的
- 3楼网友:青灯有味
- 2021-02-12 04:55
我想应该很难实现,因为上面的AVR程序应用了看门狗,eeprom,PWM等,而51是没有的。如果要改的话,最重要是硬件上也要彻底的改。
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯