开源MSP430F147单片机软核添加自定义外设

来源:互联网 发布:云智能网络 编辑:程序博客网 时间:2024/05/22 05:26

          学习过nios的小伙伴应该知道nios可以添加自定义外设,下面将以为软核SCore430添加PWM外设为例,讲解如何为SCore430添加外设。

             添加外设应该了解以下几点知识:

              1.SCore430外设接口时序

              2.SCore430的memory map

              3.外设控制器ExphCtrl源码的添加新增外设接口

           SCore430的外设接口时序

         主机接口

名称

说明

out_writeexphaddr[15:0]

写外设地址

out_writeexphdata[15:0]

写外设数据

out_writeexphbyten[1:0](可选)

16bit数据分为两个字节,对应out_writebyten的两个bit位,当对应位置位时,对应字节有效。有这个信号的原因是430指令集中大部分指令有16bit和8bit两种操作模式

out_writeexphen

写数据使能,当时钟上升沿到来,且此信号为高电平时,数据被写入。

out_readexphaddr[15:0]

读外设寄存器地址,用作数据选择器的输入参数,从而输出指定寄存器数据。

 

        外设接口

名称

说明

in_clk

系统时钟

in_rst

系统复位

in_writeaddr[15:0]

写数据地址

in_writeen

写数据使能

In_writebyten[1:0] (可选)

数据的字节使能

in_writedata[15:0]

写入的数据

in_readaddr[15:0]

读数据地址

out_readdata[15:0]

读取数据输出

 

        SCore430内存区域划分


              上图是TI官方文档MSP430x1xx系列的内存映射图,从图中可以看出外设内存地址范围是010h~1FFh,并且010~0FFh范围了只支持8bit的字节访问,SCore430没         有此限制。

              010h~1FFh地址范围大部分地址已被标准外设占用,但是我们可以不添加无用的标准外设,将地址让出来,留给自定义外设使用。

 

         SCore430外设控制器的源码修改

         在写自定义外设前首先确定外设有几个寄存器(为了操作和理解方便,在此规定所有寄存器为16bit),然后为这些寄存器分配地址。打开quartus II工程目录下的 symbol.v文件

/*******************************************************************

*建立时间:2013.12.20                  作者:李广敏,all rightsreserved

*邮箱:523659033@qq.com          版本:V1.0              

*修改时间:                                        修改人:

*功能:符号定义文件,包含指令名称和外设寄存器名称

/******************************************************************/

/*************单操作数指令************/

`define PUSH    5'b00100

`define SWPB   5'b00001

`define SXT                 5'b00011

`define RRA     5'b00010

`define RRC               5'b00000

`define CALL   5'b00101

/***********跳转指令**********/

`define JC          3'b011

`define JZ         3'b001

`define JGE       3'b101

`define JL 3'b110

`define JMP      3'b111

`define JN         3'b100

`define JNC       3'b010

`define JNE       3'b000

/**********双操作数指令***********/

`define MOV    4'b0100

`define ADD 4'b0101

`define ADDC 4'b0110

`define DADD 4'b1010

`define SUB 4'b1000

`define SUBC 4'b0111

`define CMP 4'b1001

`define AND 4'b1111

`define BIC 4'b1100

`define BIS 4'b1101

`define BIT 4'b1011

`define XOR 4'b1110

/*************复位地址*************/

`define RESET 16'h8002

/**************外设地址***************/

/******P1**************/

`define P1DIR  16'h0022

`define P1OUT  16'h0021

`define P1IN  16'h0020

/*********P2************/

`define P2DIR 16'h002a

`define P2OUT 16'h0029

`define P2IN  16'h0028

/******Multipilier*****/

`define MPY    16'h0130

`define MPYS 16'h0132

`define MAC              16'h0134

`define MACS   16'h0136

`define OP2    16'h0138

`define RESLO  16'h013a

`define RESHI   16'h013c

`define SUMEXT       16'h013e

 

          文件后面内容是外设地址定义,假设我们PWM只有一个寄存器,占空比寄存器,可以在symbol.v最后接着乘法器地址后面写入`define DUTY    16’h0140     

          当外设寄存器当做16bit访问时,地址必须为偶数。

         所有外设可以共用同一条写入总线,但是数据输出总线要分离,通数据选择器送入SCore430内部,外设控制器ExphCtrl主要充当数据选择器的作用。打开ExphCtrl.v文件。

/*******************************************************************

*建立时间:2013.12.20                  作者:李广敏,all rightsreserved                

*邮箱:523659033@qq.com          版本:V1.0

*修改时间:                                        修改人:

*功能:外设访问控制器,对外设反馈的数据,根据读取地址,

*选择正确的外设数据传送给memctrl模块

/******************************************************************/

`include "symbol.v"

module ExphCtrl(

                   inputin_clk,

                   inputin_rst,

                   /**********memctrlinterface************/

                   input[15:0]in_exphreadaddr,    //外设寄存器读地址

                   outputreg[15:0] out_exphdata,         //读外设数据接口

                   /***********exphinterface*************/

      /****P1 port***/

                   input[15:0]in_readP1data,    

                   /*****MultiplierPort***/

                   input[15:0]in_readmultiplier,

                   /******P2  Port******/

                   input[15:0]in_readP2data

);

 

 

/***********************************************

*对外设反馈的数据根据地址选择,时钟上升沿输出数据,

*当用户添加自定义外设时,需要修改此always模块

/**********************************************/

always@(posedge in_clk)

begin

         case(in_exphreadaddr)

         /************P1Interface***********/

         `P1DIR:    out_exphdata <= in_readP1data;

         `P1OUT:   out_exphdata <= in_readP1data;

         `P1IN:       out_exphdata <= in_readP1data;

         /*************P2interface************/

         `P2DIR:    out_exphdata <= in_readP2data;

         `P2OUT:   out_exphdata <= in_readP2data;

         `P2IN:       out_exphdata <= in_readP2data;

         /************MultiplierInterface*****/

         `MPY:                 out_exphdata <=in_readmultiplier;

         `MPYS:     out_exphdata <= in_readmultiplier;

         `MAC:                out_exphdata <=in_readmultiplier;

         `MACS:     out_exphdata <= in_readmultiplier;

         `OP2:                  out_exphdata <=in_readmultiplier;

         `RESLO:    out_exphdata <= in_readmultiplier;

         `RESHI:     out_exphdata <= in_readmultiplier;

         `SUMEXT:          out_exphdata <= in_readmultiplier;

         default:out_exphdata <= 0;

         endcase

end

endmodule

 

          可以看出,外设控制器中代码就是一个数据选择器,首先增加我们自定义外设的数据反馈接口 input[15:0]  in_readpwmdata

          在case语句块中添加对PWM反馈数据的选择

   Case(in_exphreadaddr)

     …

     …

     `DUTY: out_exphdata <= in_readpwmdata;

     …

     ...

   Endcase

          外设控制器修改完成,最后修改好的文件可以查看附件提供的最新工程。

PWM外设添加

         PWM代码可以查阅附件工程中文件,在此对PWM定义端口做出解释说明

modulePWM(

                            input in_clk,

                            input in_rst,

                            input[15:0]in_writeaddr,

                            input in_writeen,

                            input[15:0]in_writedata,

                            input[15:0]in_readaddr,

                            output reg[15:0]out_pwmdata,

                            output regout_pwmout

                   );

           可以看出,PWM包含了上面提到外设接口除了In_writebyten[1:0]外的所有必需接口,out_readdata被重命名为out_pwmdata,out_pwmout是用户自定义端口。

      按照上述步骤添加PWM文件并且修改symnol.v和ExphCtrl.v后,开始按下图创建PWM和ExphCtrl的符号文件。

 

          打开CPUCore430.bdf顶层文件添加PWM并更新ExphCtrl

               找到ExphCtrl模块,右键更新如上图所示。


                    更新后可以发现多出了我们添加的in_readPwmdata接口,此接口为下面添加的PWM模块的数据反馈接口


                 双击空白处,弹出上图画框,在project目录下选择PWM模块添加到P2MODULE下方,如下图所示


                  将PWM左边数据接口与左边数据总线连接,连接方式参照P2MODULE,所以外设输入端口与数据总线连接方式相同。将out_pwmdata与ExphCtrl增加的                in_readPwmdata端口相连。


            右键PWM为out_pwmout添加pin管脚。

        

到此外设添加工作完毕,可以编译工程检测有没有错误。

C语言代码驱动外设

#include<msp430x14x.h>       
#define  PwmDuty   (* (int*)0x140)     //0x140对应symbol.v中语句`define DUTY 16'h0140
void delay()                                             //100Mhz主频,每条指令机器周期6~8
{
  int i,j;
  for(i=0;i<1000;i++)
    for(j=0;j<1000;j++);
}


int main( void )
{
  
  char counter = 0;
   while(1)
   {
      delay();
     PwmDuty = counter++;
   }
   return 0;
}

按照文件件包V1.1中的《使用手册》编译此文件,将最终转换获得mif文件添加到quartusII工程中,将out_pwm管脚与LED连接,运行时即可看到LED呼吸灯。

各位可以按照此方法添加自己的外设(无中断请求功能)。具有中断功能的V2.0版将会再两个月内完成。


    所有软件设置和代码编写以最新文件包中的《使用手册》知道为准。

文件包V1.1  http://pan.baidu.com/s/1sjB8veP

0 0