wang_jiayou 发表于 2012-10-3 23:19:48

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个模块同时能用的程序就更好了

wang_jiayou 发表于 2012-10-3 23:21:37

尝试TCCR2 = (1<<COM20)|(1<<WGM21)|(1<<CS20); 这样写也不行,问题出在那啊,调试1晚上了还没有搞定,崩溃了

lngdzph 发表于 2012-10-4 01:00:31

TIMSK = TIMSK | 0xC0;                        // 0B11000000;         // OCIE2 = 1,TOIE2=1
这里有一处错误,应该是TIMSK2;
TIMSK2|=0xc0;

lngdzph 发表于 2012-10-4 01:19:03

你用的是什么型号的单片机?

wang_jiayou 发表于 2012-10-4 01:56:57

我用的 是meg128 各位帮忙我 呵呵 到底是怎么搞的啊

wang_jiayou 发表于 2012-10-4 02:01:48

lngdzph 发表于 2012-10-4 01:00 static/image/common/back.gif
TIMSK = TIMSK | 0xC0;                        // 0B11000000;         // OCIE2 = 1,TOIE2=1
这里有一处 ...

是TIMSK没有错,

wang_jiayou 发表于 2012-10-4 11:18:29

TCCR2 = (1<<COM20)|(1<<WGM21)|(1<<CS20);   发现系统调用这个就复位了 这是怎么回事情啊

zh-cho-hong 发表于 2012-10-4 14:20:01

有pwm中断函数没,如果没有的话加上一个哪怕是空函数也行。试试看,我之前也碰到过

lngdzph 发表于 2012-10-5 00:38:27

没用过128,刚刚看了下技术文档,应该是没有中断函数,TIMER2溢出时,中断函数未执行,TOV2标志位没有被清零,一直有中断请求,所以卡那儿了。。。
还有8分频应该置位CS21;

wang_jiayou 发表于 2012-10-22 08:47:50

问题解决了 呵呵 , 是中断函数没有写

hamipeter 发表于 2012-10-22 09:59:07

记个号!

zhuangchao12 发表于 2012-10-22 10:09:39

留用参考一下
页: [1]
查看完整版本: PWM和串口冲突问题