This program is directly transplanted from msp430f42x. It can be used normally after only changing the port. Therefore, the 430 module is universal in different series, and the relevant registers are the same; only the external ports may be different. Program initialization part: complete the initialization of TA related registers. char TAPwmInit(char Clk,char Div,char Mode1,char Mode2) { TACTL = 0; //Clear previous settings TACTL |= MC_1; //Set timer TA to up counting mode switch(Clk) //Select clock source { case 'A': case 'a': TACTL|=TASSEL_1; break; //ACLK case 'S': case 's': TACTL|=TASSEL_2; break; //SMCLK case 'E': TACTL|=TASSEL_0; break; //External input (TACLK) case 'e': TACTL|=TASSEL_3; break; //External input (TACLK negation) default : return(0); //Parameter error} switch(Div) //Select division factor { case 1: TACTL|=ID_0; break; //1 case 2: TACTL|=ID_1; break; //2 case 4: TACTL|=ID_2; break; //4 case 8: TACTL|=ID_3; break; //8 default : return(0); //Parameter error} switch(Mode1) //Set the output mode of PWM channel 1. { case 'P':case 'p': //If set to high-level mode TACCTL1 = OUTMOD_7; //High-level PWM output P1SEL |= BIT2; //Output from P1.2 (may be different for different MCU models) P1DIR |= BIT2; //Output from P1.2 (may be different for different MCU models) break; case 'N':case 'n': //If set to low-level mode TACCTL1 = OUTMOD_3; //Low-level PWM output P1SEL |= BIT2; //Output from P1.2 (may be different for different MCU models) P1DIR |= BIT2; //Output from P1.2 (may be different for different MCU models) break; case '0':case 0: //If set to disable P1SEL &= ~BIT2; //P1.2 returns to normal IO port break; default : return(0); //Parameter error} switch(Mode2) //Set the output mode of PWM channel 1. { case 'P':case 'p': //If set to high-level mode TACCTL2 =OUTMOD_7; //High-level PWM output P1SEL |= BIT3; //Output from P1.3 (may be different for different MCU models) P1DIR |= BIT3; //Output from P1.3 (may be different for different MCU models) break; case 'N':case 'n': //If set to low-level mode TACCTL2 =OUTMOD_3; //Low-level PWM output P1SEL |= BIT3; //Output from P1.3 (may be different for different MCU models) P1DIR |= BIT3; //Output from P1.3 (may be different for different MCU models) break; case '0':case 0: //If set to disable P1SEL &= ~BIT3; //P1.3 returns to normal IO port break; default : return(0); //Parameter error} return(1); } The main function is to set the TACTL register, let TA work in the increase mode, set the clock source and frequency division; CCTLx sets the corresponding output mode; and turn on the second function of the corresponding port. Set the period function: set the period of the PWM waveform, the unit is the number of TACLK cycles. void TAPwmSetPeriod(unsigned int Period) { TACCR0 = Period; } When working in the increase mode, TA counts to TACCR0, and sets CCR0 to complete the period setting. Set the duty cycle: set the time of the effective level of TA's PWM output. void TAPwmSetDuty(char Channel,unsigned int Duty) { switch(Channel) { case 1: TACCR1=Duty; break; case 2:TACCR2=Duty; break; } } Set the parameters of each channel according to the parameters. Set the duty cycle in thousandths: * Input parameter: Channel: the current channel number 1/2 Percent: the thousandth of the PWM effective time (0~1000) * Output parameter: None* Description: 1000=100.0% 500=50.0%, and so on* Example: TAPwmSetPermill(1,300) sets the duty cycle of PWM channel 1 square wave to 30.0% TAPwmSetPermill(2,825) sets the duty cycle of PWM channel 2 square wave to 82.5% */ void TAPwmSetPermill(char Channel,unsigned int Percent) { unsigned long int Period; unsigned int Duty; Period = TACCR0; Duty = Period * Percent / 1000; TAPwmSetDuty(Channel,Duty); } This function uses thousandths to set the effective time of PWM output. It is convenient for program use. Regarding timers, TI provides a large number of routines, which are very concise and clear. If you need other functions, you can write corresponding programs according to the routines. That's all for the program implementation. Here's how to use this program. Usage example: Usage: Still add c files to the project; the file includes h header files; then you can use this function normally. Refer to the example project and main.c for details. The main program is as follows: #include "msp430x16x.h" //430 register header file #include "TAPwm.h" //TA PWM output library header file void main() { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; ClkInit(); TAPwmInit('A',1,'P','P'); //Initialize timer TA as PWM generator //Clock source = ACLK; No frequency division; Channel 1 and channel 2 are both set to high level mode. TAPwmSetPeriod(500); //The PWM square wave period of channel 1/2 is set to 500 clock cycles TAPwmSetDuty(1,200); //1 channel is effective for 200 clock cycles TAPwmSetPermill(2,200); //2 channel 20.0% LPM0; } This program calls the library to generate two PWM waveforms. This is the end of TA's PWM output. If more PWM waves are needed, TB can be used, which can generate 6 complete PWM waveforms; you can refer to this program to write a waveform output program for TB.