芯片引脚
数据手册:MSP430F552x、MSP430F551x 混合信号微控制器 datasheet (Rev. N) (ti.com.cn)
参考代码
TI官网资料提供例程:
#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
ADC12CTL0 = ADC12SHT02 + ADC12ON; // Sampling time, ADC12 on
ADC12CTL1 = ADC12SHP; // Use sampling timer
ADC12IE = 0x01; // Enable interrupt
ADC12CTL0 |= ADC12ENC;
P6SEL |= 0x01; // P6.0 ADC option select
P1DIR |= 0x01; // P1.0 output
while (1)
{
ADC12CTL0 |= ADC12SC; // Start sampling/conversion
__bis_SR_register(LPM0_bits + GIE); // LPM0, ADC12_ISR will force exit
__no_operation(); // For debugger
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = ADC12_VECTOR
__interrupt void ADC12_ISR(void)
#elif defined(__GNUC__)
void __attribute__ interrupt(ADC12_VECTOR) ADC12_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(ADC12IV,34))
{
case 0: break; // Vector 0: No interrupt
case 2: break; // Vector 2: ADC overflow
case 4: break; // Vector 4: ADC timing overflow
case 6: // Vector 6: ADC12IFG0
if (ADC12MEM0 >= 0x7ff) // ADC12MEM = A0 > 0.5AVcc?
P1OUT |= BIT0; // P1.0 = 1
else
P1OUT &= ~BIT0; // P1.0 = 0
__bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
break;
case 8: break; // Vector 8: ADC12IFG1
case 10: break; // Vector 10: ADC12IFG2
case 12: break; // Vector 12: ADC12IFG3
case 14: break; // Vector 14: ADC12IFG4
case 16: break; // Vector 16: ADC12IFG5
case 18: break; // Vector 18: ADC12IFG6
case 20: break; // Vector 20: ADC12IFG7
case 22: break; // Vector 22: ADC12IFG8
case 24: break; // Vector 24: ADC12IFG9
case 26: break; // Vector 26: ADC12IFG10
case 28: break; // Vector 28: ADC12IFG11
case 30: break; // Vector 30: ADC12IFG12
case 32: break; // Vector 32: ADC12IFG13
case 34: break; // Vector 34: ADC12IFG14
default: break;
}
}
功能实现
在参考代码的基础上,实现功能:通过模拟数字转换器(ADC)采样输入电压V_Int,并使用OLED显示屏显示采样电压V_Int和计算后的输出电压V_Out。
定义全局变量和函数原型
results
数组用于存储采样结果。sum
用于累加采样结果。acom
和com
用于计算滤波后的电压值。cap
和flag
用于中断服务函数中的计数和标志。V_Int
和V_Out
用于存储输入和输出电压值。
函数定义
CLK_Init
:初始化时钟源,设置系统时钟。ADC_Init
:初始化ADC模块,配置ADC的相关参数。ADC_date
:从ADC读取数据并将其转换为电压值。OLED_Flag
:在OLED屏幕上显示电压值。ADC12ISR
:ADC中断服务函数,用于处理采样数据并计算滤波后的电压值。
main
函数
- 首先关闭看门狗定时器。
- 调用
CLK_Init
和ADC_Init
函数进行时钟和ADC的初始化。 - 调用
OLED_Init
函数初始化OLED显示屏。 - 在无限循环中,调用
ADC_date
函数读取电压值,并通过OLED_Flag
函数显示在OLED屏幕上。
CLK_Init
函数
- 设置时钟源,包括PLL和晶振的相关配置。
ADC_Init
函数
- 配置ADC模块,包括选择输入通道、设置采样时间、启动ADC转换等。
ADC_date
函数
- 读取ADC寄存器的值,并将其转换为电压值。
OLED_Flag
函数
- 将
V_Int
和V_Out
的值显示在OLED屏幕上。
ADC12ISR
中断服务函数
- 在ADC转换完成后被调用,存储采样结果到
results
数组。 - 对数组中的值进行平均滤波,计算滤波后的电压值
com
。 - 当采样次数达到10次时,关闭ADC中断,以便主函数可以继续执行。
完整main.c代码
//端口P6.6采样输入电压V_Int,未设置采样V_Out
//使用OLED显示采样电压
#include <msp430.h>
#include <stdio.h>
#include <stdlib.h>
#include "oled.h"
#include "bmp.h"
#include <type.h>
u32 results[10];
u32 sum = 0, acom = 0, com = 0;
u32 cap = 0, flag = 0;
float V_Int, V_Out; // 分别用于存储输入和输出电压值
// 函数原型声明
void CLK_Init(void);
void ADC_Init(void);
float ADC_date();
void OLED_Flag(void);
// 主函数
int main(void)
{
// 关闭看门狗定时器
WDTCTL = WDTPW | WDTHOLD;
// 初始化时钟和ADC
CLK_Init();
ADC_Init();
// 初始化OLED显示
OLED_Init();
// 在OLED屏幕上显示提示信息
OLED_ShowString(7,4,"V_Int : ",8);
OLED_ShowString(7,6,"V_Out : ",8);
// 主循环
while(1)
{
// 读取ADC采样值
V_Int = ADC_date();
// 调用OLED_Flag函数显示电压值
OLED_Flag();
}
}
// 时钟初始化函数
void CLK_Init(void)
{
// 设置P2.2为时钟输出
P2DIR |= BIT2;
P2SEL |= BIT2;
// 设置P7.7为时钟输出
P7DIR |= BIT7;
P7SEL |= BIT7;
// 设置P5.2和P5.3为时钟选择
P5SEL |= BIT2 + BIT3;
// 选择不使用外部晶振
UCSCTL6 &= ~XT2OFF;
// 设置参考电压源
UCSCTL3 |= SELREF_2;
// 设置时钟频率选择
UCSCTL4 |= SELA_2 + SELS_5 + SELM_5;
// 等待时钟源稳定
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
SFRIFG1 &= ~OFIFG;
}
while(SFRIFG1 & OFIFG);
// 设置时钟输出驱动能力
UCSCTL6 &= ~XT2DRIVE0;
}
// ADC初始化函数
void ADC_Init(void)
{
// 设置P6.6为ADC输入
P6SEL |= BIT6;
// 初始化ADC12模块
ADC12CTL0 = ADC12ON + ADC12SHT0_8 + ADC12MSC;
// 设置ADC12的采样保持时间
ADC12CTL1 = ADC12SHP + ADC12CONSEQ_2;
// 设置ADC12的输入通道
ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_6;
// 启动ADC转换
ADC12CTL0 |= ADC12ENC;
// 启动ADC12的采样转换
ADC12CTL0 |= ADC12SC;
// 使能ADC12中断
_EINT();
}
// 采样数据转换函数
float ADC_date()
{
// 启动ADC转换并等待完成
ADC12CTL0 |= ADC12SC;
// 读取ADC结果
float date = ADC12MEM0;
// 将ADC结果转换为电压值
date = date * 3.3 / 4065;
// 返回转换后的电压值
return date;
}
// 显示电压值的函数
void OLED_Flag(void)
{
// 在OLED屏幕上显示V_Int和V_Out的值
OLED_ShowVI(65,4,V_Int,8);
OLED_ShowVI(65,6,V_Out,8);
}
// ADC中断服务函数
#pragma vector = ADC12_VECTOR
__interrupt void ADC12ISR(void)
{
// 静态变量用于存储采样次数
static unsigned int m, count = 0;
// 滤波系数
float factor = 0.80566;
// 存储当前采样值
results[count] = ADC12MEM0;
// 增加采样次数
count++;
// 累加所有采样值
for(m = 0; m < 10; m++)
{
sum += results[m];
}
// 计算平均值
sum /= 10;
// 应用滤波系数
sum = sum * factor;
// 存储滤波后的值
com = sum;
// 如果采样次数达到10次
if(count == 10)
{
// 重置采样次数
count = 0;
// 设置标志位
flag = 1;
// 关闭ADC中断
ADC12IE = 0x00;
}
}
OLED模块请见下一篇:05:OLED模块【MSP430F5529】_msp43o5529-CSDN博客