用MSP430F5529 LauchPad作为是实验板,IAR Embedded Workbench IDE-MSP430为工具,根据要求及下方部分代码完成实验二,给出完整代码。
实验二:
通过对MSP430F5529开发板编程,从IO口产生一个25Hz方波信号,并用AD模块测量该方波信号的峰值幅度值显示于OLED上,要求:
1、利用MSP430定时器和通用IO产生25Hz方波。
2、利用MSP430内部AD测量出该方波峰值幅度并显示在OLED上。
详细要求如下:
1.利用定时器和IO口产生方波
初始化IO口设置,初始化定时器设置并是能中断,编写中断函数内改变IO口的高低电平
2.利用AD测量方波的峰值幅度
设置ADC对应的IO口为复用输入模式,使能参考电压、打开AD转换功能;设置采样时钟源及参数、参考电压大小,使能中断、使能转换,编写ADC12中断函数,在中断函数中读取ADC采样值并对采样值进行转换得到电压实际值。
main.c
#include <msp430.h>
#include "IIC.h"
/**********************
PWM波输出端口定义
***********************/
void init_IO(void)
{
//指定输出端口选择复用模式
//指定输出端口为输出模式
}
/*********************
PWM波输出定时器配置
(此代码使用TA0.1输出PWM 由P1.2输出 可自行修改为其他端口)
********************/
int Vpp=0; //幅值
int ccr0= //初始化频率(根据下面的定义自行计算)
int ccr1= //初始化占空比 (根据下面定义自行计算)
void timer_A0_1_init() //TA0.1输出PWM 由P1.2输出
{
//ACLK,增计数 (也可以选择其他时钟源,自行选择)
//输出模式7
TA0CCR0 = ccr0; //时钟频率为32768HZ(ACLK)
TA0CCR1 = ccr1; //占空比为CCR1/CCR0
}
/********************
ADC配置模块
(以下注释配置并不唯一,仅供参考,可以自行选择需要用的寄存器来进行配置)
*******************/
void ADC_init()
{
//AD接入端口复用
//端口输出模式选择为输入
//配置ADC12CTLx使能参考电压
//配置ADC12CTLx打开AD,设置采样时钟
//配置ADC12CTLx配置采样保持、分频系数、时钟源、转换序列
//配置ADC12MCTLx设置参考电压源以及参考电压大小
//配置ADC12IE使能AD中断
//配置ADC12CTLx使能AD转换
}
void delayms(int t) //延时t ms
{
while(t--)
{
int m=200;
while(m--);
}
}
/*******************
计算采样出来的电压值
(提供一种方法,仅供参考,可以自行写)
***************/
int get_Vpp() //得到Vpp
{
int n;
int min=0,max=4095,temp;
for(n=0;n<1000;n++)
{
temp=ADC12MEM0;
if(temp<min)
min=temp;
if(temp>max)
max=temp;
}
return //返回一个计算后的电压值(自行写出计算公式)
}
void LCD_Show() //LCD显示函数
{ LCD_ShowString(8,8,"Vpp=",16);
LCD_ShowString(72,8,"mV",16);
LCD_ShowNum(40,8,Vpp,4,16);
}
void init() //初始化
{
__enable_interrupt();
init_IO();
timer_A0_1_init();
ADC_init();
LCD_Init();
init_key();
}
void main( void )
{
WDTCTL = WDTPW + WDTHOLD; //关闭开门狗
init(); //初始化
while(1){
Vpp=get_Vpp();
LCD_Show();
}
}
这里是附加的IIC.c代码
#include "msp430.h"
#include "IIC.h"
#include "font.h"
//IIC延时函数
void IIC_delayus(unsigned int i)
{
unsigned int j,k;
for(k=0;k<i;k++)
for(j=0;j<4;i++);
}
//IIC初始化函数
void IIC_ioinit()
{
P6DIR|=BIT1|BIT5; //配置IIC IO口为输出方向
P6REN|=BIT1|BIT5; //配置IIC IO口使能上拉电阻
}
//开始一个IIC通信
void IIC_start()
{
SCL_HIGH;
SDA_HIGH;
//IIC_delayus(2);
SDA_LOW;
//IIC_delayus(2);
SCL_LOW;
}
//停止IIC通信
void IIC_stop()
{
SCL_LOW;
SDA_LOW;
//IIC_delayus(2);
SCL_HIGH;
SDA_HIGH;
//IIC_delayus(2);
}
//IIC发送一个byte
void IIC_writebyte(unsigned char IIC_byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(IIC_byte&0x80)
SDA_HIGH;
else
SDA_LOW;
SCL_HIGH;
SCL_LOW;
IIC_byte<<=1; //loop
}
SDA_HIGH;
SCL_HIGH;
SCL_LOW;
}
void IIC_writecmd(unsigned char IIC_command)
{
IIC_start();
IIC_writebyte(0x78); //Slave address,SA0=0
IIC_writebyte(0x00); //write command
IIC_writebyte(IIC_command);
IIC_stop();
}
void IIC_writedata(unsigned char IIC_data)
{
IIC_start();
IIC_writebyte(0x78);
IIC_writebyte(0x40); //write data
IIC_writebyte(IIC_data);
IIC_stop();
}
/**************************LCD 设置坐标*******************************/
void LCD_Set_Pos(unsigned char x, unsigned char y)
{
IIC_writecmd(0xb0+y);
IIC_writecmd(((x&0xf0)>>4)|0x10);
IIC_writecmd((x&0x0f)|0x01);
}
/***************************LCD复位************************************/
void LCD_CLS(void)
{
unsigned char y,x;
for(y=0;y<8;y++)
{
IIC_writecmd(0xb0+y);
IIC_writecmd(0x01);
IIC_writecmd(0x10);
for(x=0;x<X_WIDTH;x++)
IIC_writedata(0);
}
}
/***************************LCD初始化************************************/
void LCD_Init(void)
{
IIC_ioinit();
IIC_writecmd(0xAE); //display off
IIC_writecmd(0x20); //Set Memory Addressing Mode
IIC_writecmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
IIC_writecmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
IIC_writecmd(0xc8); //Set COM Output Scan Direction
IIC_writecmd(0x00);//---set low column address
IIC_writecmd(0x10);//---set high column address
IIC_writecmd(0x40);//--set start line address
IIC_writecmd(0x81);//--set contrast control register
IIC_writecmd(0x7f);
IIC_writecmd(0xa1);//--set segment re-map 0 to 127
IIC_writecmd(0xa6);//--set normal display
IIC_writecmd(0xa8);//--set multiplex ratio(1 to 64)
IIC_writecmd(0x3F);//
IIC_writecmd(0xa4);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content
IIC_writecmd(0xd3);//-set display offset
IIC_writecmd(0x00);//-not offset
IIC_writecmd(0xd5);//--set display clock divide ratio/oscillator frequency
IIC_writecmd(0xf0);//--set divide ratio
IIC_writecmd(0xd9);//--set pre-charge period
IIC_writecmd(0x22); //
IIC_writecmd(0xda);//--set com pins hardware configuration
IIC_writecmd(0x12);
IIC_writecmd(0xdb);//--set vcomh
IIC_writecmd(0x20);//0x20,0.77xVcc
IIC_writecmd(0x8d);//--set DC-DC enable
IIC_writecmd(0x14);//
IIC_writecmd(0xaf);//--turn on oled panel
LCD_CLS();
LCD_Set_Pos(0,0);
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 16/12
void LCD_ShowChar(unsigned char x,unsigned char y,unsigned char chr,unsigned char Char_Size)
{
unsigned char c=0,i=0;
c=chr-' ';//得到偏移后的值
if(x>Max_Column-1)
{
x=0;
y=y+2;
}
if(Char_Size ==16)
{
LCD_Set_Pos(x,y);
for(i=0;i<8;i++)
IIC_writedata(F8X16[c*16+i]);
LCD_Set_Pos(x,y+1);
for(i=0;i<8;i++)
IIC_writedata(F8X16[c*16+i+8]);
}
else
{
LCD_Set_Pos(x,y);
for(i=0;i<6;i++)
IIC_writedata(F6x8[c][i]);
}
}
//显示一个字符号串
void LCD_ShowString(unsigned char x,unsigned char y,unsigned char *chr,unsigned char Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0')
{
LCD_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>128)
{
x=0;
y+=2;
}
j++;
}
}
//m^n函数
unsigned long oled_pow(unsigned char m,unsigned char n)
{
unsigned long result=1;
while(n--)result*=m;
return result;
}
//显示一个数字
void LCD_ShowNum(unsigned char x,unsigned char y,unsigned long num,unsigned char len,unsigned char size2)
{
unsigned char t,temp;
//unsigned char enshow=0;
for(t=0;t<len;t++)
{
temp=(num/oled_pow(10,len-t-1))%10;
/*if(enshow==0&&t<(len-1))
{
if(temp==0)
{
LCD_ShowChar(x+(size2/2)*t,y,' ',size2);
continue;
}else enshow=1;
}*/
LCD_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
}
}
最新发布