受教黑金文档,再度优化兼容irq uart代码

主要修改了函数类型,兼容了普通和增强型中断

主要函数如下:

(1)uart_regs.h

(2)mcu_uart.h

(3)mcu_uart.c

(4)sys_main.c

 

//--------------------------------------------------------------------------

/*
* uart_regs.h
*
*  Created on: 2011-4-4
*      Author: CrazyBingo
*/

#ifndef UART_REGS_H_
#define UART_REGS_H_

#define _UART

//-----------------------------------------
typedef struct
{
     //接收寄存器
     union
     {
         struct
         {
             volatile unsigned long int RECEIVE_DATA    :8;
             volatile unsigned long int NC                :24;
         }BITS;
         volatile unsigned long int WORD;
     }RXDATA;

     //収送寄存器
     union
     {
         struct
         {
             volatile unsigned long int TRANSMIT_DATA    :8;
             volatile unsigned long int NC                :24;
         }BITS;
         volatile unsigned long int WORD;
     }TXDATA;

     //状忞寄存器
     union
     {
         struct
         {
            volatile unsigned long int PE        :1;
            volatile unsigned long int FE        :1;
            volatile unsigned long int BRK        :1;
            volatile unsigned long int ROE        :1;
            volatile unsigned long int TOE        :1;
            volatile unsigned long int TMT        :1;
            volatile unsigned long int TRDY        :1;
            volatile unsigned long int RRDY        :1;
            volatile unsigned long int E        :1;
            volatile unsigned long int NC        :1;
            volatile unsigned long int DCTS        :1;
            volatile unsigned long int CTS        :1;
            volatile unsigned long int EOP        :1;
            volatile unsigned long int NC1        :19;
         }BITS;
         volatile unsigned long int WORD;
     }STATUS;
     //控刢寄存器
     union
     {
         struct
         {
             volatile unsigned long int IPE        :1;
             volatile unsigned long int IFE        :1;
             volatile unsigned long int IBRK    :1;
             volatile unsigned long int IROE    :1;
             volatile unsigned long int ITOE    :1;
             volatile unsigned long int ITMT    :1;
             volatile unsigned long int ITRDY    :1;
             volatile unsigned long int IRRDY    :1;
             volatile unsigned long int IE        :1;
             volatile unsigned long int TRBK    :1;
             volatile unsigned long int IDCTS    :1;
             volatile unsigned long int RTS        :1;
             volatile unsigned long int IEOP    :1;
             volatile unsigned long int NC        :19;
         }BITS;
         volatile unsigned long int WORD;
     }CONTROL;
     //波特率分频器
     union
     {
         struct
         {
             volatile unsigned long int BAUD_RATE_DIVISOR    :16;
             volatile unsigned long int NC                  :16;
         }BITS;
         volatile unsigned int WORD;
     }DIVISOR;
}UART_STR;

#ifdef _UART
#define UART    ((UART_STR *)UART_BASE)
#endif

#endif /* UART_REGS_H_ */

 

//--------------------------------------------------------------------------

/*
* uart.h
*
*  Created on: 2011-4-4
*      Author: CrazyBingo
*/

#ifndef MCU_UART_H_
#define MCU_UART_H_

#include "../inc/uart_regs.h"

#define BUFFER_SIZE 200
typedef struct{
                 unsigned char    mode_flag;      //xmodem 1;uart 0;
                 unsigned int    receive_flag;
                 unsigned int    receive_count;
                 unsigned char    receive_buffer    [BUFFER_SIZE];
                 alt_u8            (* send_byte)    (unsigned char data);
                 void             (* send_string)    (unsigned int len, unsigned char *str);
                 alt_u8            (* init)        (void);
                 alt_u8            (* baudrate)    (unsigned int baudrate);
}UART_T;
extern UART_T uart;
#endif /*MCU_UART_H_*/

 

//--------------------------------------------------------------------------

/*
* uart.c
*
*  Created on: 2011-4-4
*      Author: CrazyBingo
*/

#include <system.h>
#include "alt_types.h"
#include "sys/alt_irq.h"

#include "../inc/uart_regs.h"
#include "../inc/mcu_uart.h"

static alt_u8    uart_send_byte(unsigned char data);
static void     uart_send_string(unsigned int len, unsigned char *str);
static alt_u8     uart_init(void);
static alt_u8     uart_set_baudrate(unsigned int baudrate);

#ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
static void uart_ISR(void* context);
#else
static void uart_ISR(void* context, alt_u32 id);
#endif

 

//初始化 UART结构体
UART_T uart=
{
     .mode_flag        =    0,
     .receive_flag    =    0,
     .receive_count    =    0,
     .send_byte        =    uart_send_byte,
     .send_string    =    uart_send_string,
     .init            =    uart_init,
     .baudrate        =    uart_set_baudrate
};

//发送一个字节数据
//将发送的数据放到发送数据缓冲区内,等待状态寄存器 TRDY置 1,当 TRDY置 1,说明接收完毕
static alt_u8 uart_send_byte(unsigned char data)
{
    UART->TXDATA.BITS.TRANSMIT_DATA = data;
    while(!UART->STATUS.BITS.TRDY);
    return 0;
}

//发送字符串
static void uart_send_string(unsigned int len, unsigned char *str)
{
    while(len--)
    {
        uart_send_byte(*str++);
    }
}

//设置波特率
static alt_u8 uart_set_baudrate(unsigned int baudrate)
{
     //设置波特率:波特率 = 时钟频率/(divisor+1),转换以后就是下面了
     UART->DIVISOR.WORD = (unsigned int)(ALT_CPU_FREQ/baudrate + 0.5);
     return 0;
}

//初始化程序
static alt_u8 uart_init(void)
{
    //默认为115200bps
    uart_set_baudrate(115200);

    //对控制寄寄存器的irrdy进行置1,表示当接收准备好后,中断使能
    UART->CONTROL.BITS.IRRDY = 1;

    //清除状态寄存器,这是处理整个寄存器的方法,大家注意
    UART->STATUS.WORD = 0;

    //注册uart中断,ISR为uart_ISR
    #ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT    //nios2 91 edition or later
    alt_ic_isr_register
    (
        UART_IRQ_INTERRUPT_CONTROLLER_ID,        // 中断控制器标号,从system.h复制
        UART_IRQ,                                 // 硬件中断号,从system.h复制
        uart_ISR,                                 // 中断服务子函数
        0,                                      // 指向与设备驱动实例相关的数据结构体
        0                                        // flags,保留未用
    );
    #else                                        //before nios2 91 edition
    alt_irq_register
    (
        UART_IRQ,                                // 硬件中断号,从system.h复制
        0,                                    // 指向与设备驱动实例相关的数据结构体
        uart_ISR                                // 中断服务子函数
    );
    #endif
    return 0;
}

//串口中断
#ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
static void uart_ISR(void* context)
#else
static void uart_ISR(void* context, alt_u32 id)
#endif
{
    //等徃状态寄存器的接收数据状态位rrdy,当rrdy位为1时,说明新接收癿值传输到了接收数据寄存器
    while(!(UART->STATUS.BITS.RRDY));

    //reveive_buffer为我们通过栈的方式在内存中开设内存块,将接收数据寄存器中的数据放到这个内存块中
    uart.receive_buffer[uart.receive_count++] = UART->RXDATA.BITS.RECEIVE_DATA;

    //当接收数据的最后一位为\n(回车符)时,进入if语句,也就是说,\n作为了结束标志
    //符,每次发送数据后,要加一个回车符作为结束符
    if(uart.receive_buffer[uart.receive_count - 1]=='\n')
    {
        uart.receive_buffer[uart.receive_count] = '\0';
        uart_send_string(uart.receive_count, uart.receive_buffer);
        uart.receive_count = 0;
        uart.receive_flag = 1;
    }
}

 

 

//--------------------------------------------------------------------------

/*
* sys_main.c
*
*  Created on: 2011-4-1
*      Author: CrazyBingo
*      irq, timer, DMA, uart
*/

#include <stdio.h>
#include "unistd.h"
#include "system.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "io.h"
#include "altera_avalon_pio_regs.h"

#include "../inc/my_sopc.h"
#include "../inc/key_scan.h"
#include "../inc/mcu_uart.h"

int main(void)
{
    //------------------------------------------------------------
    //uart test
    unsigned char buffer[50] = "I will successfully one day!\n";
    uart.init();

    while(1)
    {
        uart.send_string(sizeof(buffer), buffer);
        usleep(1000000);
    }

    return 0;
}

 

 

OK  Go  on, 谢谢

posted on 2011-04-04 21:26  CrazyBingo  阅读(1782)  评论(0编辑  收藏  举报

导航