This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 从计时器中断B0触发ADC12,只与计时器A0一起使用

Guru**** 2539500 points
Other Parts Discussed in Thread: MSP430FR5969

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/638612/trigger-adc12-from-timer-interrupt-b0-just-works-with-timer-a0

主题中讨论的其他部件:MSP430FR5969
#include "MSP430.h"
#include <ouncinics.h>
#include
<match.h>

// define for CE pin of 8*8 dot
#define CEon()(P1OUT |= BIT5);
#define CEoff()(P1OUT &=~BIT5);


// ISR Flags
volatile Estatic




= 0;易失性= 0;RS1OUT = 0;易失性= 0;易失性= 0;易失性= 0
挥发性浮点adcSegFloat =0;
挥发性无符号长adcSeg =0;
挥发性int temp =0;

// 8*8点矩阵
挥发性uint16_t TXdata8dot8变量[4]={0x00,0x00,0x00,0x00,0x00};
挥发性uint16_t shapeLineVerRed[8]=~~0x00,~0x00,0x00,~~0x00,0x00,0x00 ~0x30,~0x70,~0xF0};
volatile uint16_t shapeLineVerGreen[8]={~0x01,~0x03,~0x07,~0x0F,~0x1F, ~0x3F,~0x3F,~0x3F};
挥发性uint16_t硬币=0;

void buttonS2Call (void);
void timerCall (void);
void adcCall (void);
void DOstatic (void);
void SPIwrite(uint16_t write);


//////////////////////////// 从ISR-Flag////////////////////////////////调用函数

void buttonS2Call(void)
{//
	Button Port 4 interrupt call function
	//将ISRcall设置为
	ISRcall=0;
	debounc2=1;
	//在上模式下启动计时器,Div 8,CCR0=1000,给出T=80ms
	}TB0CTL = TBSSEL_2 + MC_1 + ID_3;


void TimerCall(void)
{ IS2=1000; s2=ducate=0)
	
	
	
				
				
				
				IF (countS2 >= 800)
					{
					//重置计数
					器countS2 = 0;
					debounce2=0;
					//停止计时器
					TB0CTL |= MC_0;
					//在WFP 1.1
					上启用中断|= BIT5;//下降边缘
					P4IFG &=~BIT5;//中断标志在调用
					P4IE |= BIT5时变为1; //端口引脚中断启用
					}
	
}}

void adcCall(void)
{//
	ADC on again and Start Comnversion
	ADC12CTL0|= ADC12ON;
	ADC12CTL0|=(ADC12ENC | ADC12SC);

	//用4096/544将数据段分成8个数据段,用math.h
	adcSeg =(long)圆


	点/来自ISR/回电
	



void DOTstatic()
{

	IF (CONOM=0)
		{//

		以下显示了彩色
		//红色LED
		TXdata8dot8[0]= shapeLineVerRed[adcSeg];
		//蓝色关闭
		TXdata8dot8[2]= 0xFF; //蓝色关闭
		//绿色LED
		TXdata8dot8[1]= shapeLineVerGreen[adcSeg];
		TXdata8dot8[3]=(0x24);

	CEoff(); 					//当CE为低时,显示屏接收数据
	SPIwrite(TXdata8dot8[0]); //传输数据[0](红色)
	SPIwrite(TXdata8dot8[2]); //传输数据[2](绿色)
	SPIwrite(TXdata8dot8[1]); //传输数据[1](蓝色)
	SPIwrite(TXdata8dot8[3]); //传输数据[3]矩阵显示
	CEON ();					//当CE为High

		时}

	其它
	{
	// LED的关闭时间
	TXdata8dot8[0]=0xFF;				//关闭
		TXdata8dot8[2]= 0xFF; //颜色蓝色关闭
		TXdata8dot8[1]= 0xFF;			//绿色关闭
		TXdata8dot8[3]=(0x18);

	CEoff(); 					//当CE为低时,显示屏接收数据
	SPIwrite(TXdata8dot8[0]); //将数据[0]传输到矩阵(红色)
	SPIwrite(TXdata8dot8[2]); //将数据[2]传输到矩阵(绿色)
	SPIwrite(TXdata8dot8[1]); //将数据[1]传输到矩阵(蓝色)
	SPIwrite(TXdata8dot8[3]); //将数据传输[3]到矩阵
	CEon();					//当CE为High时,表示矩阵开始显示
	}

void

SPIwrite(uint16_t write)
{
	CEoff();
	//循环此处直到缓冲区就绪
	//填充TXbuffer whily(!(UCB0IFG
	& UCTXIFG))){;}//
	
		
	

	加载缓冲
	区UCB0TXBUF = WRITE;

	//必须延迟100US!
	//不带最后一个字节不能解码
	__DELAY周期(100);
}

int main(void)
{
	WDTCTL = WDTPW | WDTHOLD; //停止看门狗

//禁用GPIO通电默认高阻抗模式要激活
//先前配置的端口设置,这很重要
PM5CTL0 &=~LOCKLPPM5;


//////////////////////////////////////// Clock to SMCLK=1MHz////////////////////////
//将时钟设置为最小DCO 1MHz,用户指南第104页
CSCTL0_H = CSCKEY >> 8; //解锁时钟寄存器
CSCTL1 = DCOFSEL_0 | DCORSEL; //使用DCOFsel_0
CSCTL2 = LAST__VLOCLK | SESL__DCOCLK | SELM__DCOCLK;
CSCTL3 = DIVA__1 | DIV__1 | DIVM__1; //设置所有分隔器
CSCTL0_H = 0; //锁定CS寄存器


//////////////////////////////////// GPIOs////////////////////////////////////////////////////////////////////////
//在端口WFP 4.5 上配置开关,直接连接到GND,不带上拉////////

	P4DIR &=~BIT5;//定义方向WFP 4.5 =输入
	P4REN |= BIT5;//定义上拉启用WFP 1.1
	P4OUT |= BIT5;//定义下拉不下拉

	P4IES |= BIT5;//降缘
	P4IFG &=~BIT5;//中断标志在
	被调用为PIE4时变为1; //端口引脚中断启用

//配置端口WFP 4.6 和WFP 1.0 上的LED,直接连接到GND,无需上拉////////
	P4DIR |= BIT6;//定义方向WFP 4.6 =输出
	P1DIR |= BIT0;//定义方向WFP 1.0 =输出

	P4OUT |= BIT6;//输出至1
	P1OUT |= BIT0;//输出至1

////// 计时器B0////////////////////////////////////////////////////
//////// 计时器A0////////////////////////////////////////////////////////
	TB0CCTL0 = CCIE; // TBCCR0中断已启用
	TB0CCR0 = 1万; // PWM周期
	TB0CCTL1 = OUTMOD_2; // TBCCR1重置/设置
	TB0CCR1 = 5000; // TBCCR1 =1
	// SMCLK,1MHz,MC1=上行模式,除法器8,定时器已通过MC_0禁用
	TB0CTL = TBSSEL_2 + MC_0 + ID_3;////TB0CTL
	= TBSSEL__SMCLK | MC__UP;

////// SPI B0////////////////////////////////////////////////////////
	//在配置SPI,GPIO之前设置UCSWRST
	UCB0CTLW0 |= UCSWRST;
	// P2SELB=1;P2SELB= 0将0.2 2.2 设置为1.2 CLK USCIB0,第84页
	P2SEL1 ||(BIT2); //
	P1SEL0 &=~(BIT2);
	// P1SEL1 = 1,P1SEL0 = 0将Periph设置为SPI或I2C ->请参阅第83页上的数据表	//WFP 1.7 = UCB0SOMI
	//WFP 1.6 = UCB0SIMO
	P1SEL0 &=~(BIT6|BIT7); //
	P1SEL1 ||(BIT6|BIT7);						//引脚方向由eUSI_B0设置
	// GPIO作为软件NSS
	P1DIR || BIT5;//定义方向WFP 1.5 =输出
	P1OUT || BIT5;//输出至1

	//初始化SPI模式3.
	UCB0CTLW0 = UCCKPL| UCMST | UCMODE_0 | UCSYNC | UCMSB |UCSSEL__SMCLK |UCSWRST;// SPI模式3需要UCCKPL =1 ->空闲时钟高,UCCKPH=0 ->在第一个故障边缘写入;
	//Master,UCMODE_0->3 -线默认模式,Synchron,Keep UCSWRST == 1或什么都没有发生!

	//为100kHz SPI时钟设置Prescaler Prescale=1MHz/100kHz=10
	UCB0BRW=10;
	//这将从重置中释放USCIB0
	UCB0CTLW0 &=~UCSWRST;
	//接收时RX启用中断
	// UCB0IE |= UCRXIE;//////

ADC A10引脚4.2
	//配置GPIO,电位计10kOhm位于VCC,(WFP 4.2 GPO->A10),(WFP 2.6 ->GND)
	// WFP 2.6 输出并设置为Low
	P2DIR |= BIT6;
	P2OUT &=~BIT6;
	// P4SEL1 = 1;P4SELb 0.2 = 1第94页
	P4SEL1 ||(BIT2); //
	P4SEL0 ||(BIT2);

	// CTL寄存器0:在CTL Regiser中进行任何更改之前设置ADC12ON位
	// ADC12=N位,ADC12SHT1用于ADC10和16个周期
	//采样16个周期,从10*TAU=10*27pF*5k和时钟6.3MHz到舍入[cyles]=10TAU*fclk
	ADC12CTL0 = ADC12ON | ADC12SHT1_2;
	// CTL寄存器1:单转换CONSEQ0,时钟选择ADC内部ADC120SC为模式0,3为smclk,无时钟分频器
	//从ADC12SC触发采样和保持源
	ADC12CTL1 = ADC12CONSEQ0 | ADC12SSEL_0 | ADC12DIV0 | ADC12SHS0;
	// CTL寄存器2:ADC12DF = 0,对于二进制无符号格式0x0000...0xFFFF,ADCRESolution 12位
	ADC12CTL2 = ADC12RES_2;
	//选择MEM寄存器非常重要,如果没有,则不会进入ISR
	ADC12CTL3 = ADC12CSTARTADD_10;
	// ADC10的转换存储器控制寄存器,参考设置为VCC,ADC12VRSEL=0的GND
	ADC12MCTL10 = ADC12INCH_10;

	//寄存器0中的Interrups ADC10
	ADC12IER0 = ADC12IE10;


	_BIS_SR_REGISTER (GIE); //启用中断

时(1)
	{

	SWITCH(ISRcall)
		{
		案例1: timerCall(); break;//计时器每隔50毫秒唤醒CPU并设置ISRcall=1;
		案例2:__no_operation();break;//不执行任何操作
		案例3: buttonS2Call(); break;//打开CPRcall=1;案例2:__register 4.5

		(CPUSR;}
		
		
	}


}//

按钮S1左
侧#pragma vector=Port4_vector
__interrupt void Port4_ISR(void)
{//
	为按钮调用
	ISRcall=3设置标志;

	//切换绿色LED
	P1OUT ^=BIT0;
	//关闭红色切换LED
	P4OUT &=~BIT6;

	//清除标记或卡在开关ISR
	P4IFG中~;// BIT5; // Flag register
	P4IE &=~BIT5;// Portpin Interrupt Disable
}//

ISR for Timer A0//////////////////////////////////////////////
#pragma vector=TIMER0_B0_vector
__interrupt void Timer_B0 (void)
{//

	Timer interrupt every 1000*8/1MHz =8ms
	// toggle variable cin
	cin^= cino;
	//设置计时器的标志调用
	ISRcall=1;
}//

ADC中断
#pragma vector = ADC12_vector
__interrupt ADC12_MECAM10 (void)


	
	//禁用转换
	ADC12CTL0 &=~ADC12ENC;
	ADC12CTL0 &=~ADC12ON;

	//切换红色LED
		P4OUT ^=BIT6;
}//


SPI Inerrupt
#pragma vector = USCI_B0_Vector
__interrupt void USCRX0_Rx_ISR (void)
{//RXUUUUUF;
	
}


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,

    下面是我的电平计代码的一个帖子,应该在MSP430FR5969上运行。 很遗憾,目前还没有。

    ADC12用于感应直流电压,并由计时器B0每8毫秒触发一次。 直流电压分为8段,并通过SPI发送,以显示在8个RGB LED上。 此过程由交换机启动并运行几秒钟。

    使用计时器A0时,程序工作正常,在程序中放置断点时,我看到ADC值发生了变化,并且在电平表上放置LED指示灯。
    使用计时器B0时,ADC永远不会到达ADC ISR。 在ADC ISR中添加断点时,至少我看不到程序正在执行。 将断点放置到ADC调用函数时,ADC值始终为0。 这是上面的代码。 当将所有内容更改为定时器A0时,它似乎工作正常。

    我还尝试了计时器A1,但这不适用于上述注册设置。

    在纯软件模式下使用计时器时,我对输出模式和如何选择TA0CCR1感到有点困惑,请您给出一些想法的提示吗? 使用硬件PWM时,我了解CCR0和CCR1设置的原因,例如占空比。 在这里,我只想进入ISR,时间TAR每次都转到CCR0,然后得到ADC值。 我是否还可以使用TACR1进入ISR? 所有计时器A0,A1,B0是否都有自己的CCR0,CCR1,CCR2寄存器,以及是否对所有这些都正确,使用CCR0时,中断标志被自己清除,使用CCR1和CCR2时, 需要在开关壳体上读取计时器Vektor (例如TA0 TA0IV)以清除标记?

    很抱歉我的所有初学者问题,我希望你们中的一些人有时间帮助您浏览代码。

    最后一个一般性问题。 在ISR函数中设置标志是否有意义,在ISR完成且程序返回while (1)循环后,ISR函数调用正常函数(我称为“呼叫函数”)?

    此致
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Audio Designer,

    您是否尝试过更改ADC12CTL1寄存器的ADC12SHSx位? 您的代码指示值001b,该值从TA0 CCR1输出触发ADC。 查看数据表的表6-18,如果您要将此值更改为010B或011b,则ADC将分别从TB0 CCR0或CCR1输出触发。

    TIMER0_A0_Vector处理CCR0中断,而TIMER0_A1_Vector处理TA0的CCR1,CCR2和CTL中断。 TA1和TB0也是如此。 ISRcall标志是合乎逻辑的,应尽快退出ISR。

    此致,
    Ryan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    亲爱的Ryan!

    非常感谢您的回答。 ADC12的ADC12SHSx位是正确设置计时器的正确点。

    要使用计时器B0,我必须将位设置为011b -> TB0 CCR1输出。

    最初我在软件触发器代码中有ADC12SHS0 =000b。 为什么这只适用于定时器A0? 软件触发器不是指,我可以使用任何计时器,并通过在计时器ISR中写入以下代码来启动ADC转换?

    //再次打开ADC并启动Comnversion
    ADC12CTL0 || ADC12ON;
    ADC12CTL0|=(ADC12ENC | ADC12SC);

    然后在转换完成时清除这些位。

    我的目标是在CCR0上进行一个转换,在CCR1上进行另一个转换,然后等待计时器再次从0开始。 是否可以使用一个计时器执行此操作,或者是否必须使用两个计时器并更改ADCSHS位?


    此致
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,AD,

    ADC只能触发来自一个源(ADC12SC或TAxCCRn输出)的转换,因此您需要相应地调整计时器频率或ISR以进行补偿。 ADC12SC将与任何定时器ISR一起工作,但您的代码已将ADC12SHS0设置为ADC12SHSx值001b (TA0 CCR1输出触发器)。

    此致,
    Ryan