三进制通信核心代码

//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);
		}
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值