PWM和串口冲突问题
//***********************************************************************// 包含文件
//***********************************************************************
#define F_CPU 16000000
#include <avr/interrupt.h> //中断信号头文件
#include <avr/io.h>
#include <compat/ina90.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include "define.h"
#include <avr/wdt.h>
void portinit(void);
void spi_enable(void);
void spi_disable(void);
void send_zero(void);
void send_one(void);
void contron_ab(void);
unsigned int tx_count=200,tx_flag=0xff;
unsigned char usart_tx_data;
unsigned char usart_rx_data;
unsigned char aa[]="100 first start!";
unsigned char ab[]="&100 starting!";
//*************************************************************************
// 串口初始化,RS485使用串口1,按照使用串口的方式初始化即可
//*************************************************************************
void usart_init()
{
UCSR1A=0x00; //单倍速模式
UCSR1B=0x98; //接收中断和发送中断允许
UCSR1C=(1<<UCSZ11)|(1<<UCSZ10); //写UCSRC寄存器,异步通信无校验,8位数据1位停止位
UBRR1H=baud_h; //写波特率的值
UBRR1L=baud_l;
}
//*************************************************************************
// 串口相关中断服务子程序
//*************************************************************************
//数据发送结束中断向量
SIGNAL(SIG_USART1_TRANS) //中断服务程序
{
delay_ms(10); //相关操作
}
void usart_send(unsigned char data)
{
CTR_H;
while ( !(UCSR1A & (1<<UDRE1)) );
UDR1 = data; //接收到的数据再发回电脑
delay_ms(2);
CTR_L;
}
//数据接收结束中断向量
SIGNAL(SIG_USART1_RECV) //中断服务程序
{
CTR_L;
usart_rx_data=UDR1; //将接收到的数据取出
}
int put_char(unsigned char c)
{
CTR_H;
UDR1 = c;
while (!(UCSR1A & (1<<UDRE1)));
CTR_L;
}
void put_string(unsigned char *s,unsigned int len)
{
unsigned char i=0;
//根据485速度 确定是否加延时函数防止通行误码
CTR_H;
delay_ms(10);
for(i=0;i<len;i++)
{
put_char(*s);
s++;
}
put_char(0x0a);
delay_ms(10);
put_char(0x0d);
delay_ms(10);
delay_ms(10);
CTR_L;
}
void put_uchar(unsigned char b)
{
BYTE aa="INT000";
aa = b/100%10 + '0';
aa = b/10%10 + '0';
aa = b%10 + '0';
put_string(aa,6);
}
void put_uint(unsigned int b)
{
BYTE aa="INT00000";
aa = b/10000%10 + '0';
aa = b/1000%10 + '0';
aa = b/100%10 + '0';
aa = b/10%10 + '0';
aa = b%10 + '0';
put_string(aa,8);
}
void put_ulong(unsigned long b)
{
BYTE aa[]="LONG0000000000";
aa = b/1000000000%10 + '0';
aa = b/100000000%10 + '0';
aa = b/10000000%10 + '0';
aa = b/1000000%10 + '0';
aa = b/100000%10 + '0';
aa = b/10000%10 + '0';
aa = b/1000%10 + '0';
aa = b/100%10 + '0';
aa = b/10%10 + '0';
aa = b%10 + '0';
put_string(aa,14);
}
void Open_SSP(unsigned char LTIME)
{
//asm("CLI");
DDRB = (1<<PB7); // DDRB第7位为输出口
PORTB = PORTB | 0x80; //DDRB第7位置位
TCCR2 = 0;//TCCR2 = TCCR2|0x1a;// 0b00011010WGM = 10; COM = 01; CS2 = 010; 做8分频
TCCR2 = TCCR2|0x19;// 发现这样写和其他波特率冲突,原因不知道
// TCCR2 = (1<<COM20)|(1<<WGM21)|(1<<CS20);
TIFR =TIFR| 0xC0; // 0b11000000; // OCF2=1,TOV2=1,先把中断标志清零
//* 定时器2到时中断和溢出中断开
TIMSK = TIMSK | 0xC0; // 0B11000000; // OCIE2 = 1,TOIE2=1
//* 定时器2到时中断和溢出中断开
OCR2 =LTIME;
TCNT2 = 0;
//asm("SEI");
}
void contron_a(void)
{
DDRF =(1<<PF1);
A_1;
}
void contron_b(void)
{
DDRA =(1<<PA4);
B_1;
}
void contron_b1(void)
{
DDRA =(1<<PA4);
B_0;
}
void contron_200K(void)
{
DDRD =(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
C_0;
D_0;
E_0;
F_0;
}
void contron(void)
{
DDRD =(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
C_0;
D_0;
E_0;
F_1;
}
/*********
void timer1_init()
{
SREG=0x80; //使能全局中断
TCCR1A=0x00; //配置定时器工作在普通模式
TCCR1B=0x01; //无分频
TIMSK=(1<<TOIE1); //使能定时溢出中断
TCNT1H=0xff;
TCNT1L=0xdf; //65535-(16m/8)2.5*(10的负6次方)
}
SIGNAL(SIG_OVERFLOW1)
{
PORTB^=(1<<PB0);
TCNT1H=0xff;
TCNT1L=0xdf; //65535-(16m/8)2.5*(10的负6次方)
}
void timer0_init(void)
{
TCCR0 = 0x00; //停止
TCNT0 = 0xE2; //计算1ms装入值C2为226
TCCR0 = 0x03; //启动定时器32分频 Time=32*(255-226+1)/16000000=60uS
TIMSK|=(1<<TOIE0); //定时器0溢出中断使能
}
SIGNAL(SIG_OVERFLOW0)
{
TCNT0 = 0xE2; //计算1ms装入值C2为132 =0x84
TIMSK&=~(1<<TOIE0); //T0溢出中断禁止
TCCR0 = 0x00; //停止计时器
TCCR0 = 0x03; //启动定时器64分频 Time=64*(255-132+1)/8000000=0.001S
TIMSK|=(1<<TOIE0); //定时器0溢出中断使能
}
************/
//*************************************************************************
// 主程序
//*************************************************************************
int main(void)
{
unsigned char welcome="&100WELCOME!!";
cli();
usart_init(); //usart串口初始化配置
portinit();
DDRD =(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
DDRA =(1<<PA4);
DDRF =(1<<PF1);
contron_200K();
Open_SSP(39);
GP2_init();
wdt_enable(WDTO_500MS);
wdt_reset(); //看门狗计数清零
WDTCR=0x1F; //
WDTCR=0x0F; //使能watchdog,并且,采用2048K分频,典型溢出时间5V时2.1S
sei(); //总中断允许位
put_string(welcome,13);
while(1){
wdt_reset();
put_string(welcome,13);
}
}
这个程序单个的PWM模块和串口通讯都没有问题,但是PWM 和串口同时用就不能通讯了, TCCR2 = TCCR2|0x19;把这个屏蔽了通讯正常了,问题出在那,高手帮忙解答一下啊,能发个这2个模块同时能用的程序就更好了
尝试TCCR2 = (1<<COM20)|(1<<WGM21)|(1<<CS20); 这样写也不行,问题出在那啊,调试1晚上了还没有搞定,崩溃了 TIMSK = TIMSK | 0xC0; // 0B11000000; // OCIE2 = 1,TOIE2=1
这里有一处错误,应该是TIMSK2;
TIMSK2|=0xc0; 你用的是什么型号的单片机? 我用的 是meg128 各位帮忙我 呵呵 到底是怎么搞的啊 lngdzph 发表于 2012-10-4 01:00 static/image/common/back.gif
TIMSK = TIMSK | 0xC0; // 0B11000000; // OCIE2 = 1,TOIE2=1
这里有一处 ...
是TIMSK没有错, TCCR2 = (1<<COM20)|(1<<WGM21)|(1<<CS20); 发现系统调用这个就复位了 这是怎么回事情啊 有pwm中断函数没,如果没有的话加上一个哪怕是空函数也行。试试看,我之前也碰到过 没用过128,刚刚看了下技术文档,应该是没有中断函数,TIMER2溢出时,中断函数未执行,TOV2标志位没有被清零,一直有中断请求,所以卡那儿了。。。
还有8分频应该置位CS21; 问题解决了 呵呵 , 是中断函数没有写 记个号! 留用参考一下
页:
[1]