⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 MEGEA64控制的TUNER程序
💻 C
字号:
#include <avr/interrupt.h>
#include <string.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/boot.h>
#include <util/delay.h>
#include <util/twi.h>
#include <avr/wdt.h>

#define PORTC_INTERFACE

volatile unsigned int  timer0_counter;
volatile unsigned char g_ucTWI_Send_Buff[10];
volatile unsigned char send_number_of_bytes;
volatile unsigned int  div_16bit;
volatile unsigned char channel_change_byte_flag;
volatile unsigned char channel_busy_byte_flag;

#define BYTE_FLAG_TRUE      0xff
#define BYTE_FLAG_FALSE     0x00

#define SET_FLAG(a)         (a=BYTE_FLAG_TRUE)
#define CLEAR_FLAG(a)       (a=BYTE_FLAG_FALSE)

volatile unsigned char Div1,Div2,Con2;

#define FOSC                                7372800
#define BAUD                                115200
#define TIMER0_RELOAD_VALUE                 22

#define FUENCY          38900                                          /* 中频频率          */
#define PLLdataH(f)     (unsigned char)((f+FUENCY)*16/1000/256)        /* 频率数据高 第1字节*/
#define PLLdataL(f)     (unsigned char)((f+FUENCY)*16/1000%256)        /* 频率数据低 第2字节*/
#define PLLCON1         0x8e                                           /* 控制字1    第3字节*/
                                                                       /* 控制字2    第4字节*/
#define PLLCON2(f)      (((f)<(168000))?(0xa0):(((f)<(450000))?(0x90):(0x30)))
#define PLLdata3(fchan) {PLLdataH(fchan), PLLdataL(fchan), PLLCON2(fchan)}

#define Nop()           asm("nop")

volatile unsigned char channel;
void SetChan(unsigned char chan);
unsigned char ReadChan(void);
void PutChar(unsigned char send_char);
void PutAscii(unsigned char hex_data);
void PutEnter(void);
void put_string(const unsigned char * str);

const unsigned char start_string[] = "Start OK!";
const unsigned char current_channel_string[] = "Current Channel:";
const unsigned char read_set_channel_string[] = "FeedbackValue:";

const unsigned long freq[] = 
{
 49750,
 57750,
 65750,
 77250,
 85250,
 
112250,
120250,
128250,
136250,
144250,
152250,
160250,
168250,
176250,
184250,
192250,
200250,
208250,
216250,
224250,
232250,
240250,
248250,
256250,
264250,
272250,
280250,
288250,
296250,
304250,
312250,
320250,
328250,
336250,
344250,
352250,
360250,
368250,
376250,
384250,
392250,
400250,
408250,
416250,
424250,
432250,
440250,
448250,
456250,
464250,
471250,
479250,
487250,
495250,
503250,
511250,
519250,
527250,
535250,
543250,
551250,
559250,
607250,
615250,
623250,
631250,
639250,
647250,
655250,
663250,
671250,
679250,
687250,
695250,
703250,
711250,
719250,
727250,
735250,
743250,
751250,
759250,
767250,
775250,
783250,
791250,
799250,
807250,
815250,
823250,
831250,
839250,
847250,
855250,
863250,
90100-6500,
91000-6500,
91800-6500,
97500-6500,
100300-6500,
103200-6500,
105000-6500,
106500-6500
};  

#define AddPllWr 0xc0                                   /*TSA5522写地址*/
#define AddPllRd 0xc1                                   /*TSA5522读地址*/

#ifdef PORTC_INTERFACE
#ifdef PORTC_INTERFACE_USED
#define     SDA     PC4<input type="button" >
#define     SCL     PC5
#define SDA_Low()       (PORTC &= ~_BV(PC4))
#define SDA_High()      (PORTC |= _BV(PC4))
#define SCL_Low()       (PORTC &= ~_BV(PC5))
#define SCL_High()      (PORTC |= _BV(PC5))
#else
#define     SDA     PD1
#define     SCL     PD0
#define SDA_Low()       (PORTD &= ~_BV(PD1))
#define SDA_High()      (PORTD |= _BV(PD1))
#define SCL_Low()       (PORTD &= ~_BV(PD0))
#define SCL_High()      (PORTD |= _BV(PD0))
#endif
#else
#define     SDA     PC1
#define     SCL     PC2
#define SDA_Low()       (PORTC &= ~_BV(PC1))
#define SDA_High()      (PORTC |= _BV(PC1))
#define SCL_Low()       (PORTC &= ~_BV(PC2))
#define SCL_High()      (PORTC |= _BV(PC2))
#endif

void Start(void); 
void Stop(void); 
void SendACK(void); 
void SendNoACK(void); 
unsigned char SendByte(unsigned char d);
unsigned char ReadByte(void); 

void scl_delay(void)
{
    Nop();Nop();        /*Nop();Nop();Nop();*/
}

void delay_ms(unsigned int delay)
{
    volatile unsigned int i,a;
    for (i=0; i<delay; i++)
    {
        a = i*1;
    }
}

void calc_divider(unsigned char chan)
{
    Div1 = ((unsigned char)((freq[chan]+FUENCY)*16/1000/256)) & 0x7f;
    Div2 = (unsigned char)((freq[chan]+FUENCY)*16/1000%256);
}

unsigned char ReadChan(void)
{
    unsigned char i=0; 
    Start();                                                /* 发送I2C 总线起始条件*/
    SendByte(AddPllRd);                                         /*发送被控器总线读地址*/
    i = ReadByte(); 
    //SendNoACK();                                            /*最后一个字节,发送非应答信号*/
    Stop();                                                 /*发送I2C 总线停止条件*/
    return (i); 
}

void SetChan(unsigned char chan)
{
    //Div1 = ((unsigned char)((freq[chan]+FUENCY)*16/1000/256)) & 0x7f;
    //Div2 = (unsigned char)((freq[chan]+FUENCY)*16/1000%256);
    //Con2 = (((freq[chan])<(168000))?(0xa0):(((freq[chan])<(450000))?(0x90):(0x30)));
    Con2 = (((freq[chan])<(168000))?(0x01):(((freq[chan])<(450000))?(0x02):(0x08)));
    Start();                                                 /* 发送I2C 总线起始条件  */
    SendByte(AddPllWr);                          /* 发送被控器总线写地址    */
    SendByte(Div1);
    SendByte(Div2);
    SendByte(PLLCON1);                                 /* 发送控制字1    第3字节*/
    SendByte(Con2);
    Stop();
    //PutChar(Div1);                                                 /*发送I2C 总线停止条件   */
    //PutChar(Div2);
    SET_FLAG(channel_busy_byte_flag);
}

/*------------字节数据传送子程序发送一个字节数据或地址给被控器---------------*/
unsigned char SendByte(unsigned char a)
{
    unsigned char i; 
    for(i = 0;i < 8;i++)
    {
        if ((a & 0x80) == 0)
            SDA_Low();
        else
            SDA_High();
        scl_delay(); 
        SCL_High();
        scl_delay();            /*保证时钟高周期大于4 us*/
        SCL_Low();
        scl_delay(); 
        a = a << 1; 
    }
    SDA_High();
    scl_delay(); 
    SCL_High();
    /*  wait ack
    j = 0; 
    #ifdef PORTC_INTERFACE
    while((PINC&0x10) == 0)
        if ((++j) == 0) {SCL_Low(); return (1);}
    #else
    while((PINC&0x02) == 0)
        if ((++j) == 0) {SCL_Low(); return (1);}
    #endif
    */
    scl_delay();
    SCL_Low();
    scl_delay();
    return (0);  /*成功,返回0*/
}

/*---------------------------------------------------------------------------*/
unsigned char ReadByte(void)                /*数据接收子程序从被控器接收一个字节数据*/
{
    unsigned char i; 
    unsigned char Sin=0;
    
    #ifdef PORTC_INTERFACE
    #ifdef PORTC_INTERFACE_USED
    DDRC  = 0xEF;
    PORTC = 0xFF;
    #else
    DDRD  = 0xFD;
    PORTD = 0xFF;
    #endif
    #else
    DDRC  = 0xFD;
    PORTC = 0xFF;
    #endif
    for (i = 0;i < 8;i++)
    {
        Sin <<= 1; 
        
        SCL_High();
        scl_delay();
        
        #ifdef PORTC_INTERFACE
        #ifdef PORTC_INTERFACE_USED
        if((PINC & 0x10) == 0x10)          //PC4
            Sin |= 0x01;
        else
            Sin &= 0xfe;
        #else
        if((PIND & 0x02) == 0x02)          //PD1
            Sin |= 0x01;
        else
            Sin &= 0xfe;
        #endif
        #else
        if ((PINC & 0x02) == 0x02)          //PC1
            Sin |= 0x01;
        else
            Sin &= 0xfe;
        #endif
        
        scl_delay();
        SCL_Low();
        
        scl_delay(); 
    }
    #ifdef PORTC_INTERFACE
    #ifdef PORTC_INTERFACE_USED
    DDRC = 0xff;
    PORTC = 0xff;
    #else
    DDRD = 0xff;
    PORTD = 0xff;
    #endif
    #else
    DDRC = 0xff;
    PORTC = 0xff;
    #endif
    return(Sin); 
}

/*-----------发送应答位--------------------------------------------------*/
void SendACK()
{
    SCL_Low();
    scl_delay();
    SDA_Low();
    scl_delay();
    SCL_High();
    scl_delay();
    SCL_Low();
}

/*------------发送非应答位-----------------------------------------------*/
void SendNoACK()
{
    SCL_Low();
    scl_delay();
    SDA_High();
    scl_delay();
    SCL_High();
    scl_delay();
    SCL_Low();
}

/*---------------------------------------------------------------------------*/
void Start(void)                /*START 启动I2C 总线子程序发送I2C 起始条件*/
{
    SDA_High();
    scl_delay();
    SCL_High();
    scl_delay();
    SDA_Low();
    scl_delay();
    SCL_Low();
}

/*-----------STOP 停止I2C 总线子程序发送I2C 总线停止条件-------------------*/
void Stop(void)
{
    SDA_Low();
    scl_delay();
    SCL_High();
    scl_delay();
    SDA_High();
    scl_delay();
}

void Check_UART_Int(void)
{
    if (channel_change_byte_flag == BYTE_FLAG_TRUE)
    {
        put_string(current_channel_string);
        PutAscii(channel);
        SetChan(channel);
        #if 0
        delay_ms(50000);
        delay_ms(50000);
        PutAscii(ReadChan());
        #endif
        CLEAR_FLAG(channel_change_byte_flag);
    }
}
ISR(TIMER0_OVF_vect)
{
	TCNT0 = TIMER0_RELOAD_VALUE;
	timer0_counter++;
}

void port_init(void)
{
    DDRB  = 0xFF;
 	PORTB = 0xFF;
 	PORTC = 0xFF;
 	DDRC  = 0xFF;
    DDRD  = 0xFF;
    PORTD = 0x7F;
}

void Timer0Init(void)               /* 5 ms */
{
    TCCR0 = 0x00;
    TCNT0 = TIMER0_RELOAD_VALUE;
    TCCR0 = 0x03; 		/* prescale 1/64 */     
}

void UartInit(void)
{
	UCSR1A = 0x00;
    UCSR1C = (1<<UCSZ1)|(1<<UCSZ0);
    UBRR1L = ((FOSC/16/BAUD) -1) % 256;  //3;
    UBRR1H = ((FOSC/16/BAUD) -1) / 256;  //0;
    UCSR1B = (1<<RXEN1) | (1<<TXEN1) | (1<<RXCIE1);
}

void PutChar(unsigned char send_char)
{
    cli();
    while(!(UCSR1A&(1<<UDRE1)));
    UDR1 = send_char;
    sei();
}

void timer0_task(void)
{
    if ( timer0_counter >= 50 )    /* 5*timer0_counter ms */
    {
        timer0_counter = 0;
        if (channel_busy_byte_flag == BYTE_FLAG_TRUE)
        {
            PutChar(' ');PutChar(' ');PutChar(' ');PutChar(' ');
            put_string(read_set_channel_string);
            PutAscii(ReadChan());
            PutEnter();
            CLEAR_FLAG(channel_busy_byte_flag);
        }
    }
}

ISR(USART1_RX_vect)
{
    volatile unsigned char temp;
    temp = UDR1;
    if (temp == 0x2c)           /* '<' inc freq one step*/
    {
        if (Div2 == 0xff) {Div2 = 0; Div1++;}
        else Div2++;
    }
    else if (temp == 0x2e)      /* '>' dec freq one step*/
    {
        if (Div2 == 0) {Div1--; Div2=0xff;}
        else Div2--;
    }
    else if (temp == 'c')       /* 'c' inc channel */
    {
        if(channel++ == 103) channel = 0;
        calc_divider(channel);
    }
    else if (temp == 'x')        /* 'x' dec channel */
    {
        if(channel-- == 0) channel = 103;
        calc_divider(channel);
    }
    SET_FLAG(channel_change_byte_flag);
}


void PutEnter(void)
{
    PutChar(0x0d);
    PutChar(0x0a);
}

unsigned char str_len(const unsigned char * spr)
{
    unsigned char string_len  = 0;
    unsigned char string_data = *spr++;
    
    while(string_data != '\0')
    {
        string_len++;
        string_data = *spr++;
    }
    return string_len;
}

void put_string(const unsigned char * str)
{
    unsigned char i;
    unsigned char len;
    len=strlen(str);
    for(i=0; i<len; i++) 
    {
        PutChar(*str++);
    }
}

void PutAscii(unsigned char hex_data)
{
    unsigned char temp;
    temp = (hex_data & 0xf0) >> 4;
    if(temp<10) temp += 0x30;
    else temp += 55;
    PutChar(temp);
    temp = hex_data & 0x0f;
    if(temp<10) temp += 0x30;
    else temp += 55;
    PutChar(temp);
}

int main(void)
{
    timer0_counter = 0;
    channel = 0;
    port_init();
    Timer0Init();
    UartInit();
    TIMSK = (1<<TOIE0);
    sei();
    put_string(start_string);
    
    CLEAR_FLAG(channel_change_byte_flag);
    CLEAR_FLAG(channel_busy_byte_flag);
    channel = 0;
    calc_divider(channel);
    
    put_string(current_channel_string);
    PutAscii(channel);
    SetChan(channel);
    PutEnter();
    
    while(1)
    {
        timer0_task();
        Check_UART_Int();
    }
    return 0;   
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -