//C语言,可直接编译
#include<stdio.h>
#include<string.h>
#define max_length 512 //发送数组容量
unsigned int max_duty=90,min_duty=10; //线性范围
unsigned int origin=50; //亮度初始值
char send[max_length]; //数据发送数组
int order=0; //数组索引
void conv(unsigned char p); //3进制转换
unsigned int check(); //计算间隔值
unsigned char send_data(char* s); //发送数据
int main()
{
send_data("GZHU"); //在此处发送字符
return 0;
}
unsigned char send_data(char* s)
{
static int length,light,i;
static unsigned int interval;
length=strlen(s);
order=0;
printf("origin data:");
for(i=0;i<length;i++)
{
conv(s[i]);
printf ("%d,",s[i]);
}
printf("\r\n");
interval =check ();
printf("interval=%d\r\n",interval);
light=origin;
printf("%d\r\n",light);
for(i=0;i<order-1;i++)
printf("%d\r\n",light+=(send[i]-1)*interval);
printf("%d\r\n",origin);
return 1;
}
void conv(unsigned char p)
{
while(p!=0)
{
send[order++]=p%3;
p/=3;
}
}
unsigned int check()
{
static int sentbit,up,down,i;
static unsigned int dis;
up=down=sentbit=0;
printf("process data:");
for(i=0;i<order-1;i++)
{
sentbit+=send[i]-1;
if(sentbit<down) down=sentbit;
if(sentbit>up) up=sentbit;
printf ("%d,",send[i]);
}
printf("\r\n");
if((up+down)>0) dis=(max_duty-min_duty)/(2*up);
else dis=(max_duty-min_duty)/(2*-down);
return dis;
}
//单片机代码
#include "stm32f10x.h"
#include "GPIO.h"
#include "delay.h"
#include "string.h"
#define max_length 512
unsigned int max_duty=90,min_duty=10;
unsigned int origin=50;
char send[max_length],sending=0;
unsigned int interval;
int send_order=0,order=0;
u16 TIM1_TimerPeriod = 0; //自动重装载值
u16 duty,Channel1Pulse;
void conv(unsigned char p)
{
while(p!=0)
{
send[order++]=p%3;
p/=3;
}
}
unsigned int check()
{
static int sentbit,up,down,i;
static unsigned int dis;
up=down=sentbit=0;
for(i=0;i<order-1;i++)
{
sentbit+=send[i]-1;
if(sentbit<down) down=sentbit;
if(sentbit>up) up=sentbit;
}
if((up+down)>0) dis=(max_duty-min_duty)/(2*up);
else dis=(max_duty-min_duty)/(2*-down);
return dis;
}
void send_data(char* s)
{
static int length,i;
length=strlen(s);
order=0;
for(i=0;i<length;i++) conv(s[i]);
interval =check ();
send_order=0;
sending=1;
while(sending);
}
void GPIO_Config()
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能TIM1,GPIOA,GPIOB*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void TIM1_PWM_Config(double pfreq ,u16 psc) //pfreq为不分频时的PWM频率,psc为预分频值
{
TIM_TimeBaseInitTypeDef TIM1_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure; //输出通道配置
TIM1_TimerPeriod = (SystemCoreClock / pfreq) - 1; //自动重装载周期值
Channel1Pulse = (u16)((u32)(origin * (TIM1_TimerPeriod - 1)) / 100 ); //占空比origin
/* 初始化TIM1 */
TIM1_TimeBaseStructure.TIM_Period = TIM1_TimerPeriod; //设置重装载周期值
TIM1_TimeBaseStructure.TIM_Prescaler = psc; //设置预分频值
TIM1_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分频因子,仅与输入捕获有关(定时器与滤波器的频率比)
TIM1_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM1_TimeBaseStructure.TIM_RepetitionCounter = 0; //重复溢出中断
TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseStructure); //初始化定时器基本配置
/* Channel_1 TIM_OCMode_PWM1模式 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; //占空比 = TIM_Pulse/TIM_Period;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //有效电平为高电平
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; //输出空闲状态
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根据指定的参数初始化外设TIM1 OC2
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR2上的预装载寄存器
TIM_Cmd(TIM1, ENABLE); //使能TIM1
TIM_CtrlPWMOutputs(TIM1,ENABLE); //PWM输出使能(输出PWM的这句一定要加)
}
void TIM2_Config(double ifreq,u16 psc) //ifreq为不分频时的更新中断频率,psc为预分频值
{
static u16 TIM2_TimerPeriod;
TIM_TimeBaseInitTypeDef TIM2_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
TIM2_TimerPeriod = (SystemCoreClock / ifreq) - 1;
TIM2_TimeBaseStructure.TIM_Period = TIM2_TimerPeriod; //设置自动重装载寄存器周期值
TIM2_TimeBaseStructure.TIM_Prescaler = psc; //设置预分频值 10Khz的计数频率
TIM2_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分频系数
TIM2_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM2_TimeBaseStructure);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM2中断,允许更新中断(计数器溢出或软件初始化时)
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //主优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_Cmd(TIM2, ENABLE); //使能TIM2
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查TIM2更新中断发生与否
{
if(sending)
{
duty+=(send[send_order++]-1)*interval;
Channel1Pulse = (u16)((u32)(duty * (TIM1_TimerPeriod - 1)) / 100 );
TIM_SetCompare1(TIM1,Channel1Pulse);
if(send_order>=order) {sending=0;duty=origin;}
}
else
{
Channel1Pulse = (u16)((u32)(origin * (TIM1_TimerPeriod - 1)) / 100 );
TIM_SetCompare1(TIM1,Channel1Pulse);
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除TIM2更新中断标志
}
}
int main()
{
SysTick_Init(72);
GPIO_Config();
TIM1_PWM_Config(50000,0);
TIM2_Config(20,99);
while(1)
{
send_data("GZHU");
delay_ms(1000);
}
}