|
发表于 2010-9-21 20:57:44
|
显示全部楼层
#include "stm32f10x_lib.h"
u32 TempK[3]; //产品唯一ID号
vu32 TempA; //输入PWM的脉宽
vu32 TempB; //输入PWM的频率
vu32 TempC; //PWM1输出频率
vu32 TempD; //PWM1输出脉宽
vu32 TempE; //PWM2频率
vu32 TempF; //PWM2脉宽
vu32 TempG; //PWM3频率
vu32 TempH; //PWM3脉宽
vu32 TempI; //PWM4频率
vu32 TempJ; //PWM4脉宽
vu16 T1_H = 20000;
vu16 T1_L = 30000;
vu16 T2_H = 20000;
vu16 T2_L = 30000;
vu16 T3_H = 20000;
vu16 T3_L = 30000;
vu16 T4_H = 20000;
vu16 T4_L = 30000;
vu8 rx_flag;
vu8 tx_flag;
vu8 rx_buf[5];
vu8 tx_buf[10];
u8 rx_i,tx_i;
u8 ID_Check_Flag;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
u32 sys_frequency;
void ID_Write(void)
{
u8 i;
u32 temp = 0; //ID以字位单位的和
u16 res[3]; //存放余数
for(i = 0;i < 3;i ++)
{
TempK = *(u32*)(0x1FFFF7E8 + 4 * i);
temp += TempK;
}
res[0] = temp % 100;
res[1] = temp % 500;
res[2] = temp % 1000;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASH_ProgramHalfWord(0x0800f000,res[0]);
FLASH_ProgramHalfWord(0x0800f900,res[1]);
FLASH_ProgramHalfWord(0x0800fe00,res[2]);
FLASH_Lock();
}
void ID_Read(void)
{
u8 i;
u32 temp = 0; //ID以字位单位的和
u16 res[3]; //存放余数
u32 read_buf[3];
for(i = 0;i < 3;i ++)
{
TempK = *(u32*)(0x1FFFF7E8 + 4 * i);
temp += TempK;
}
res[0] = temp % 100;
res[1] = temp % 500;
res[2] = temp % 1000;
read_buf[0] = *(u32*)(0x0800f000) & 0xffff;
read_buf[1] = *(u32*)(0x0800f900) & 0xffff;
read_buf[2] = *(u32*)(0x0800fe00) & 0xffff;
for(i = 0;i < 3;i ++)
{
if(res != (u16)(read_buf))
{
while(1);
}
}
}
void RCC_INIT(void)
{
RCC_ClocksTypeDef RCC_Clocks;
RCC_HSEConfig(RCC_HSE_ON);
while(!RCC_WaitForHSEStartUp()); //等待HSE发生作用
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2); //最少1个等待,否则程序跑飞
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_6); //6倍频
RCC_PLLCmd(ENABLE);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //PLL时钟作为系统时钟源
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //必须先使能时钟,否则无法配置GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //必须先使能时钟,否则无法配置GPIO
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //开启TIM4时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //开启TIM3时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //开启TIM3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //开启USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); //开启TIM1时钟
RCC_GetClocksFreq(&RCC_Clocks);
sys_frequency = RCC_Clocks.SYSCLK_Frequency;
sys_frequency /= 5;
}
void NVIC_INIT(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
//开启串口中断
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//开启定时器2中断
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//开启定时器3中断
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void delays(u16 i)
{
u32 j;
for(;i > 0;i --)
for(j = sys_frequency;j > 0;j--);
}
void GPIO_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//PWM输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//PWM输入
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//TX初始化
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//RX初始化
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void TIM1_PWM_INIT(void) //TIM1配置PWM输出参数
{
u32 temp_fre,temp_duty;
TempC = 60; //设置频率初始值
TempD = 4; //设置初始占空比1 / 2
temp_fre = (1000000 / TempC) - 1;
temp_duty = ((temp_fre + 1) / TempD);
TIM_TimeBaseStructure.TIM_Prescaler = 72;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = temp_fre;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = temp_duty;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* TIM1 counter enable */
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE);
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
void TIM2_PWM_INIT(void)
{
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Output Compare Toggle Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = T1_H;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* Output Compare Toggle Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = T2_H;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* Output Compare Toggle Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = T3_H;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* Output Compare Toggle Mode configuration: Channel4 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = T4_H;
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* TIM enable counter */
TIM_Cmd(TIM2, ENABLE);
/* TIM IT enable */
TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
}
void TIM3_PWM_IN_INIT(void)
{
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
/* Select the TIM2 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
/* Enable the Master/Slave Mode */
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
}
void USART1_INIT(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
void SYS_TIM_INIT(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
SysTick_SetReload(9000); //9MHZ下,计数9000就是1ms
SysTick_CounterCmd(SysTick_Counter_Enable); //使能systick计数器
SysTick_ITConfig(ENABLE); //使能中断
}
void sys_state_get(void)
{
tx_buf[0] = TempB;
tx_buf[1] = TempA;
tx_buf[2] = TempC;
tx_buf[3] = TempD;
tx_buf[4] = TempE;
tx_buf[5] = TempF;
tx_buf[6] = TempG;
tx_buf[7] = TempH;
tx_buf[8] = TempI;
tx_buf[9] = TempJ;
}
void system_init(void)
{
TempA = 0;
TempB = 0;
TempC = 1000000 / 50000;
TempD = T1_H / 1000;
TempE = 1000000 / 50000;
TempF = T2_H / 1000;
TempG = 1000000 / 50000;
TempH = T3_H / 1000;
TempI = 1000000 / 50000;
TempJ = T4_H / 1000;
}
int main(void)
{
u32 main_temp;
RCC_INIT(); //时钟配置
NVIC_INIT(); //中断优先级配置
// ID_Write();
system_init();
GPIO_INIT(); //IO口初始化
USART1_INIT(); //串口初始化,波特率9600,其他默认
TIM2_PWM_INIT(); //TIM2的CH4通道输出PWM
TIM3_PWM_IN_INIT();
SYS_TIM_INIT();
while (1)
{
if(rx_flag == 1)
{
rx_flag = 0;
switch(rx_buf[1])
{
case 1: //修改通道1的频率,脉宽
TempC = rx_buf[2];
TempD = rx_buf[3];
if((TempC > 17) && (TempC < 255))
{
main_temp = 1000 / TempC;
if(main_temp > TempD)
{
T1_H = TempD * 1000;
T1_L = (main_temp - TempD) * 1000;
}
}
break;
case 2:
TempE = rx_buf[2];
TempF = rx_buf[3];
if((TempE > 17) && (TempE < 255))
{
main_temp = 1000 / TempE;
if(main_temp > TempF)
{
T2_H = TempF * 1000;
T2_L = (main_temp - TempF) * 1000;
}
}
break;
case 3:
TempG = rx_buf[2];
TempH = rx_buf[3];
if((TempG > 17) && (TempG < 255))
{
main_temp = 1000 / TempG;
if(main_temp > TempH)
{
T3_H = TempH * 1000;
T3_L = (main_temp - TempH) * 1000;
}
}
break;
case 4:
TempI = rx_buf[2];
TempJ = rx_buf[3];
if((TempI > 17) && (TempI < 255))
{
main_temp = 1000 / TempI;
if(main_temp > TempJ)
{
T4_H = TempJ * 1000;
T4_L = (main_temp - TempJ) * 1000;
}
}
break;
}
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //重新使能串口接收
}
}
}
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : stm32f10x_it.c
* Author : MCD Application Team
* Version : V2.0.3
* Date : 09/22/2008
* Description : Main Interrupt Service Routines.
* This file provides template for all exceptions handler
* and peripherals interrupt service routine.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
u16 capture = 0;
extern vu16 T1_H;
extern vu16 T1_L;
extern vu16 T2_H;
extern vu16 T2_L;
extern vu16 T3_H;
extern vu16 T3_L;
extern vu16 T4_H;
extern vu16 T4_L;
extern vu32 TempA; //输入PWM的脉宽
extern vu32 TempB; //输入PWM的频率
extern vu32 TempC; //PWM1输出频率
extern vu32 TempD; //PWM1输出脉宽
extern vu32 TempE; //PWM2频率
extern vu32 TempF; //PWM2脉宽
extern vu32 TempG; //PWM3频率
extern vu32 TempH; //PWM3脉宽
extern vu32 TempI; //PWM4频率
extern vu32 TempJ; //PWM4脉宽
extern vu8 rx_flag;
extern vu8 tx_flag;
extern vu8 rx_buf[5];
extern vu8 tx_buf[10];
extern u8 rx_i,tx_i;
extern u8 ID_Check_Flag;
extern void sys_state_get(void);
vu16 IC2Value = 0;
vu16 DutyCycle = 0;
* Function Name : SysTickHandler
* Description : This function handles SysTick Handler.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SysTickHandler(void)
{
static u16 i;
i++;
if(i % 1000 == 0) //1s钟串口发送一次当前的数据
{
sys_state_get();
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
if(i == 60000)
{
ID_Check_Flag = 1;
i = 0;
}
}
//*******************************************************************************
* Function Name : TIM2_IRQHandler
* Description : This function handles TIM2 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void TIM2_IRQHandler(void)
{
/* TIM2_CH1 toggling with frequency = 183.1 Hz */
static u8 i1,i2,i3,i4;
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{
i1++;
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );
capture = TIM_GetCapture1(TIM2);
if(i1 % 2 == 1)
{
TIM_SetCompare1(TIM2, capture + T1_L);
}
else
{
TIM_SetCompare1(TIM2, capture + T1_H);
}
}
/* TIM2_CH2 toggling with frequency = 366.2 Hz */
if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
{
i2++;
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
capture = TIM_GetCapture2(TIM2);
if(i2 % 2 == 1)
{
TIM_SetCompare2(TIM2, capture + T2_L);
}
else
{
TIM_SetCompare2(TIM2, capture + T2_H);
}
}
/* TIM2_CH3 toggling with frequency = 732.4 Hz */
if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
{
i3++;
TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
capture = TIM_GetCapture3(TIM2);
if(i3 % 2 == 1)
{
TIM_SetCompare3(TIM2, capture + T3_L);
}
else
{
TIM_SetCompare3(TIM2, capture + T3_H);
}
}
/* TIM2_CH4 toggling with frequency = 1464.8 Hz */
if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET)
{
i4++;
TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);
capture = TIM_GetCapture4(TIM2);
if(i4 % 2 == 1)
{
TIM_SetCompare4(TIM2, capture + T4_L);
}
else
{
TIM_SetCompare4(TIM2, capture + T4_H);
}
}
}
/*******************************************************************************
* Function Name : TIM3_IRQHandler
* Description : This function handles TIM3 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void TIM3_IRQHandler(void)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
IC2Value = TIM_GetCapture2(TIM3);
if (IC2Value != 0)
{
DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value; //占空比
TempB = 1000000 / IC2Value; //输入PWM频率
TempA = IC2Value / 1000; //输入PWM脉宽
}
else
{
DutyCycle = 0;
TempB = 0;
TempA = 0;
}
}
/ |
|