📄 dsp-spwm.c
字号:
#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
/* ----- LCD控制状态 ----- */
#define LCDDELAY 1 // DSP与LCD在命令之间的延时(因为LCD是慢速设备)
#define LCDCMDTURNON 0x3f // 打开显示
#define LCDCMDTURNOFF 0x3e // 关闭显示
#define LCDCMDSTARTLINE 0xc0 // 设置显示起始行(0~63);初始设置为从最顶行开始,索引值为0。
// 如果要离开x行后开始显示数据,则索引值为64-x,x属于1~64。当索引值为0时,就是离开64行开始显示数据,此时也就是从顶行开始显示
#define LCDCMDPAGE 0xb8 // 设置操作页(0~7);初始设置为第0页
#define LCDCMDVERADDRESS 0x40 // 设置操作列(0~63);初始设置为第0列
/* ----- ICETEK DSP教学实验箱硬件扩展模块寄存器 ----- */
// 本实验箱的LCD为:64(行)×128(列),分为64×64的左右两个半屏
#define LEDS *(int *)0xc0000 // LED灯
#define CTRGR *(int *)0x108000 // 全局控制寄存器
#define CTRLCDCMDR *(int *)0x108001 // 液晶命令寄存器
#define CTRLCDCR *(int *)0x108002 // 液晶控制寄存器
#define CTRLCDLCR *(int *)0x108003 // 液晶左半屏控制寄存器
#define CTRLCDRCR *(int *)0x108004 // 液晶右半屏控制寄存器
#define CTRLR *(int *)0x108007 // 发光二极管显示控制寄存器
#define N_spwm 129 // 一个周期包含的SPWM脉冲个数
interrupt void t1pr_isr(void); // 定时器1周期中断,以在线改变占空比
void Delay(unsigned int); // 延时子程序
void TurnOnLCD(); // 打开显示
void ClsLCD(); // 清除屏幕显示内容
void BeginLCD(); // 初始显示状态程序
void TestLCD(); // 测试状态显示程序
void init_eva_pwm(); // EVA模块的PWM初始化程序
void cmpx_calculate(int); // SPWM波占空比(比较寄存器CMPRx)计算子程序
unsigned char lednumber[12][8]= // 8×8点阵字符
{
{0x00,0x00,0x7C,0x82,0x82,0x82,0x7C,0x00}, //0
{0x00,0x00,0x00,0x84,0xFE,0x80,0x00,0x00}, //1
{0x00,0x00,0x84,0xC2,0xA2,0x92,0x8C,0x00}, //2
{0x00,0x00,0x42,0x82,0x8A,0x96,0x62,0x00}, //3
{0x00,0x00,0x30,0x28,0x24,0xFE,0x20,0x00}, //4
{0x00,0x00,0x4E,0x8A,0x8A,0x8A,0x72,0x00}, //5
{0x00,0x00,0x78,0x94,0x92,0x92,0x60,0x00}, //6
{0x00,0x00,0x02,0xE2,0x12,0x0A,0x06,0x00}, //7
{0x00,0x00,0x6C,0x92,0x92,0x92,0x6C,0x00}, //8
{0x00,0x00,0x0C,0x92,0x92,0x52,0x3C,0x00}, //9
{0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x00}, ///
{0x00,0x92,0x54,0x38,0xFE,0x38,0x54,0x92} //*
};
/* 正弦函数表采用Q15定标,作PWM占空比用 */
unsigned int sin_table[259]={0,399,798,1197,1595,1994,2392,2790,3187,3584,
3980,4376,4771,5165,5559,5952,6344,6735,7125,7514,
7901,8288,8674,9058,9440,9822,10202,10580,10957,11332,
11706,12078,12448,12816,13182,13546,13909,14269,14627,14983,
15337,15688,16037,16384,16728,17070,17409,17746,18080,18412,
18740,19066,19389,19710,20027,20341,20653,20961,21266,21568,
21867,22162,22454,22743,23029,23311,23590,23865,24137,24405,
24669,24930,25187,25440,25690,25936,26178,26416,26650,26880,
27106,27328,27547,27761,27971,28176,28378,28575,28768,28957,
29142,29322,29498,29670,29837,30000,30158,30312,30461,30606,
30746,30882,31013,31139,31261,31379,31491,31599,31703,31801,
31895,31984,32068,32148,32223,32293,32358,32419,32474,32525,
32571,32613,32649,32681,32707,32729,32746,32758,32766,32768,
32766,32758,32746,32729,32707,32681,32649,32613,32571,32525,
32474,32419,32358,32293,32223,32148,32068,31984,31895,31801,
31703,31599,31491,31379,31261,31139,31013,30882,30746,30606,
30461,30312,30158,30000,29837,29670,29498,29322,29142,28957,
28768,28575,28378,28176,27971,27761,27547,27328,27106,26880,
26650,26416,26178,25936,25690,25440,25187,24930,24669,24405,
24137,23865,23590,23311,23029,22743,22454,22162,21867,21568,
21266,20961,20653,20341,20027,19710,19389,19066,18740,18412,
18080,17746,17409,17070,16728,16384,16037,15688,15337,14983,
14627,14269,13909,13546,13182,12816,12448,12078,11706,11332,
10957,10580,10202,9822,9440,9058,8674,8288,7901,7514,
7125,6735,6344,5952,5559,5165,4771,4376,3980,3584,
3187,2790,2392,1994,1595,1197,798,399,0};
int spwm_flag; // 送出一个SPWM脉冲的标志
int I; // 当前输出第几个SPWM脉冲,I=[0~N_spwm-1]
unsigned int CMP1,CMP2,CMP3; // 根据占空比实时计算的比较寄存器值
/* ----- 系统主程序 ----- */
void main(void)
{
spwm_flag = 1; // 初始设置为已送出一个PWM脉冲
I = 0;
InitSysCtrl(); // 初始化CPU
// CLKIN=SYSCLKOUT=(30M*10.0)/2=150M
// HSPCLK=SYSCLKOUT/2=75M,即EVA、EVB、ADC模块都使用此时钟作为CPU时钟
DINT; // 关中断,即可屏蔽中断全局禁止
InitPieCtrl(); // 初始化PIE寄存器
IER = 0x0000; // 禁止所有的中断
IFR = 0x0000; // 清除全部CPU级(一级)中断标志,CPU级中断标志为写0后清零
InitPieVectTable(); // 初始化中断向量表
CTRGR = 0x80; // 初始化ICETEK-CTR
Delay(LCDDELAY);
CTRGR = 0x0;
Delay(LCDDELAY);
CTRGR = 0x80;
Delay(LCDDELAY);
CTRLR = 0; // 关闭东西方向的交通灯
Delay(LCDDELAY);
CTRLR = 0x40; // 关闭南北方向的交通灯
Delay(LCDDELAY);
TurnOnLCD(); // 打开显示
ClsLCD(); // 清除显示内存
BeginLCD(); // 初始显示状态
Delay(9000);
ClsLCD();
TestLCD();
EvaRegs.EVAIFRA.all = 0xFFFF; // 清除EVA模块的全部中断标志寄存器,防止系统误触发其他不需要的中断
EvaRegs.EVAIFRB.all = 0xFFFF;
EvaRegs.EVAIFRC.all = 0xFFFF;
EvbRegs.EVBIFRA.all = 0xFFFF; // 清除EVB模块的全部中断标志寄存器,防止系统误触发其他不需要的中断
EvbRegs.EVBIFRB.all = 0xFFFF;
EvbRegs.EVBIFRC.all = 0xFFFF;
init_eva_pwm();
EINT; // 可屏蔽中断全局使能
ERTM; // 调试事件使能
while ( 1 )
{
if( spwm_flag ==0 );
else
{
spwm_flag = 0;
cmpx_calculate(I);
I++;
if( I == 129 ) I = 0;
}
}
}
/* ----- 定时器1周期中断,以在线改变占空比 ----- */
interrupt void t1pr_isr(void)
{
EvaRegs.EVAIFRA.bit.T1PINT = 1; // 清楚T1PINT中断标志,为下一次T1PINT中断作准备
spwm_flag = 1; // 使退出中断后能进行下一个脉冲周期的占空比计算
EvaRegs.CMPR1 = CMP1;
EvaRegs.CMPR2 = CMP2;
EvaRegs.CMPR3 = CMP3;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; // Acknowledge interrupt INT2 to PIE
return;
}
/* ----- 延时子程序 ----- */
void Delay(unsigned int nDelay)
{
int ii,jj,kk=0;
for ( ii=0;ii<nDelay;ii++ )
{
for ( jj=0;jj<60;jj++ )
{
kk++;
}
}
}
/* ----- 打开显示 ----- */
void TurnOnLCD()
{
CTRLCDCMDR=LCDCMDTURNON;
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(2048);
CTRLCDCMDR=LCDCMDSTARTLINE;
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
}
/* ----- 清屏 ----- */
void ClsLCD()
{
int i,j;
CTRLCDCMDR=LCDCMDVERADDRESS;
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
for ( i=0;i<8;i++ )
{
CTRLCDCMDR=LCDCMDPAGE+i;
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
for ( j=0;j<64;j++ )
{
CTRLCDLCR=0;
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDRCR=0;
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
}
}
}
/* ----- 初始显示状态 ----- */
void BeginLCD()
{
unsigned char ledwords1[2][64]= // "静止无功",第一行为其上半字,第二行为其下半字
{
{0x40,0x44,0x54,0x54,0x7F,0x54,0x54,0x48,0x24,0x27,0xF4,0x2C,0x24,0xF0,0x20,0x00,
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x60,0x40,0x00,0x00,0x00,
0x00,0x40,0x42,0x42,0x42,0x42,0xFE,0x42,0xC2,0x42,0x43,0x42,0x60,0x40,0x00,0x00,
0x08,0x08,0x08,0xF8,0x0C,0x28,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0xF0,0x20,0x00},
{0x00,0x00,0xFF,0x15,0x15,0x95,0xFF,0x01,0x49,0x89,0x7F,0x09,0x09,0x1F,0x01,0x00,
0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x60,0x40,0x00,
0x00,0x80,0x40,0x20,0x18,0x06,0x01,0x00,0x3F,0x40,0x40,0x40,0x40,0x40,0x70,0x00,
0x08,0x18,0x08,0x0F,0x84,0x44,0x20,0x1C,0x03,0x20,0x40,0x80,0x40,0x3F,0x00,0x00}
};
unsigned char ledwords2[2][64]= // "补偿装置",第一行为其上半字,第二行为其下半字
{
{0x10,0x10,0x10,0x11,0xD6,0x30,0x98,0x00,0x00,0xFF,0x40,0x80,0x00,0x00,0x00,0x00,
0x80,0x40,0x20,0xF8,0x47,0x30,0x92,0x94,0x90,0x9F,0x90,0xD4,0x92,0x50,0x30,0x00,
0x00,0x42,0x24,0x10,0xFF,0x00,0x44,0xA4,0x24,0x3F,0x24,0x34,0x26,0x84,0x00,0x00,
0x00,0x10,0x17,0xD5,0x55,0x57,0x55,0x7D,0x55,0x57,0x55,0xD5,0x17,0x10,0x00,0x00},
{0x08,0x04,0x02,0x01,0xFF,0x01,0x02,0x00,0x00,0xFF,0x00,0x00,0x01,0x03,0x00,0x00,
0x00,0x00,0x00,0xFF,0x04,0x04,0x44,0x64,0x54,0x4C,0x44,0x54,0x64,0xC6,0x04,0x00,
0x01,0x21,0x21,0x11,0x09,0xFD,0x43,0x21,0x0D,0x11,0x29,0x25,0x43,0xC1,0x41,0x00,
0x40,0x40,0x40,0x7F,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7F,0x40,0x60,0x40,0x00}
};
unsigned char ledwords3[2][64]= // "广西大学",第一行为其上半字,第二行为其下半字
{
{0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x05,0x06,0x04,0x04,0x04,0x04,0x06,0x04,0x00,
0x04,0xC4,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0xE6,0x44,0x00,
0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x7F,0xA0,0x20,0x20,0x20,0x20,0x30,0x20,0x00,
0x40,0x30,0x11,0x96,0x90,0x90,0x91,0x96,0x90,0x90,0x98,0x14,0x13,0x50,0x30,0x00},
{0x40,0x30,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xFF,0x40,0x50,0x48,0x47,0x40,0x40,0x40,0x47,0x48,0x48,0x40,0xFF,0x00,0x00,
0x00,0x40,0x40,0x20,0x10,0x0C,0x03,0x00,0x01,0x06,0x08,0x10,0x20,0x60,0x20,0x00,
0x04,0x04,0x04,0x04,0x04,0x44,0x84,0x7E,0x06,0x05,0x04,0x04,0x04,0x06,0x04,0x00}
};
unsigned char ledwords4[2][32]= // "吴莹",第一行为其上半字,第二行为其下半字
{
{0x00,0x00,0x80,0x9E,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0xDF,0x82,0x00,0x00,0x00,
0x80,0x64,0xA4,0xA4,0xA4,0xBF,0xA4,0xA4,0xA4,0xBF,0xA4,0xA4,0x26,0xA4,0x60,0x00},
{0x04,0x84,0x84,0x44,0x44,0x24,0x1C,0x07,0x0C,0x14,0x24,0x44,0xC4,0x46,0x04,0x00,
0x40,0x40,0x44,0x44,0x44,0x44,0x44,0x7F,0x44,0x54,0x64,0x46,0x44,0x60,0x40,0x00}
};
int i,k;
unsigned int n1,n2,n3;
CTRLCDCMDR=LCDCMDPAGE; // 设置操作页=0,显示"静止无功补偿装置"的上半字
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDCMDR=LCDCMDVERADDRESS; // 起始列=0
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
for ( i=0;i<64;i++ )
{
CTRLCDLCR=ledwords1[0][i];
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDRCR=ledwords2[0][i];
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
}
CTRLCDCMDR=LCDCMDPAGE+1; // 设置操作页=1,显示"静止无功补偿装置"的下半字
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
for ( i=0;i<64;i++ )
{
CTRLCDLCR=ledwords1[1][i];
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDRCR=ledwords2[1][i];
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
}
CTRLCDCMDR=LCDCMDPAGE+2; // 设置操作页=2,显示一行"*"
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
for ( k=0;k<64;k=k+8 )
{
CTRLCDCMDR=LCDCMDVERADDRESS+k;
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
for ( i=0;i<8;i++ )
{
CTRLCDLCR=lednumber[11][i];
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDRCR=lednumber[11][i];
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
}
}
CTRLCDCMDR=LCDCMDPAGE+4; // 设置操作页=4,屏幕左侧显示"广西大学"的上半字
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDCMDR=LCDCMDVERADDRESS; // 起始列=0
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
for ( i=0;i<64;i++ )
{
CTRLCDLCR=ledwords3[0][i];
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
}
CTRLCDCMDR=LCDCMDVERADDRESS+16; // 起始列=16,操作页=4,屏幕右侧显示"吴莹"的上半字
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
for ( i=0;i<32;i++ )
{
CTRLCDRCR=ledwords4[0][i];
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
}
CTRLCDCMDR=LCDCMDPAGE+5; // 设置操作页=5,屏幕左侧显示"广西大学"的下半字
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
CTRLCDCMDR=LCDCMDVERADDRESS; // 起始列=0
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
for ( i=0;i<64;i++ )
{
CTRLCDLCR=ledwords3[1][i];
Delay(LCDDELAY);
CTRLCDCR=0;
Delay(LCDDELAY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -