vb2002 发表于 2024-8-6 16:20:37

DebugLab 发表于 2024-8-6 16:17
上电二话别说先关闭输出,然后不能操作IO,读EEPROM,再打开输出

其他档位没问题,就是微量有闪一下

DebugLab 发表于 2024-8-6 16:36:41

vb2002 发表于 2024-8-6 16:20
其他档位没问题,就是微量有闪一下

上电时序不合理呗,注意IAP操作时CPU暂停

DebugLab 发表于 2024-8-6 16:37:17

DebugLab 发表于 2024-8-6 16:36
上电时序不合理呗,注意IAP操作时CPU暂停

先读写EEPROM,再打开PWM

vb2002 发表于 2024-8-6 17:35:52

DebugLab 发表于 2024-8-6 16:37
先读写EEPROM,再打开PWM

好的,我回去试试,把pwm放在eeprom后面

vb2002 发表于 2024-8-6 18:42:18

DebugLab 发表于 2024-8-6 16:37
先读写EEPROM,再打开PWM

是这个问题,,我把PWM放在eeprom后面就好了.
但是只解决了一半,,还是有点点闪,,不过可以接受了.
之前是超级闪,现在就是一丢丢闪

DebugLab 发表于 2024-8-6 18:45:57

vb2002 发表于 2024-8-6 18:42
是这个问题,,我把PWM放在eeprom后面就好了.
但是只解决了一半,,还是有点点闪,,不过可以接受了.
之前是超 ...

上电高阻的型号,用电阻给IO口拉到不亮的电平

vb2002 发表于 2024-8-7 00:21:17

梁工 发表于 2024-8-6 15:53
上电路。


电路图
代码我也发出来吧
https://www.stcaimcu.com/data/attachment/forum/202408/06/131125q7amc0hqm0o4f880.jpg

#include "stc8g.h"
#include "intrins.h"
#include "eeprom.h"
#include <stdio.h>



#define MAIN_Fosc 11059200UL
#define BRT         (65536 - MAIN_Fosc / 115200 / 4)
//#define EEPROMId       0x0E00

typedef unsigned char u8;
typedef unsigned int u16;

u8 save;
u8 state;
u8 dat;
u16 EEPROMId = 0100;
u16 time;

bit key_flag;

//void delayms(u16 ms);   
void sys_init();
void PWM_init(void);
void Timer0_Init(void);


void UartInit()
{
    SCON = 0x5a;
    TL1 = BRT;
    TH1 = BRT >> 8;
    AUXR = 0x15;
        TR1=1;
}


//void UartSend(char dat)
//{
//    while (!TI);
//    TI = 0;
//    SBUF = dat;
//}


u8 LEDControl()
{       
//        u8 dat;

//        u16 EEPROMId = 0XE00;                                //将指针指向第8扇区的第一个字节
//        SetMode(CMD_READ);                                //设置为读取数据
       
        while(1)
        {       
                dat = IapRead(EEPROMId + 1);                        //读取下一字节数据
//                printf("%bu\r\n",dat);
//                printf("%u\r\n",EEPROMId);       
//        printf("dat= %bu\r\n",dat);
//        printf("id= %u\r\n",EEPROMId);                       
               
                if(dat == 0XFF)                                        //下一字节字节未写入数据
                {
                        dat = IapRead(EEPROMId);                //读取当前字节数据
//                        SetMode(CMD_PROGRAM);                        //写入数据
       
                        switch(dat)
                        {       
                                case 1: IapProgram(EEPROMId+1,191);break;
                                case 191: IapProgram(EEPROMId+1,121);break;
                                case 121: IapProgram(EEPROMId+1,51);break;

                                default: IapProgram(EEPROMId+1,1);break;        
                               
                        }       
                        return dat;                                        //返回当前字节数据
                }
        else                                                        //下一字节不为空,指针加一,继续判断下一个字节
                {        EEPROMId++;
                }


                if(EEPROMId >= 0XFFD)                                //如果当前字节到达EEPROM末尾,擦除扇区所有数据
                {       
//                        SetMode(CMD_ERASE);                        //扇区擦除
                        IapErase(0x0000);                                //擦除扇区
                        IapErase(0x0200);                                //擦除扇区       
                        IapErase(0x0400);                                //擦除扇区       
                        IapErase(0x0600);                                //擦除扇区       
                        IapErase(0x0800);                                //擦除扇区       
                        IapErase(0x0A00);                                //擦除扇区       
                        IapErase(0x0C00);                                //擦除扇区       
                        IapErase(0x0E00);                                //擦除扇区                               
                        return 1;
                }
        }
}


void main()
{               

        sys_init();

      UartInit();
CR=0;       
       
        LEDControl();
        CR=1;       
           PWM_init();
//   UartSend(IapRead(dat));
//   UartSend(IapRead(EEPROMId));

//   UartSend(IapRead(dat));


               
        while(1)
        {
                  CCAP1H= dat;   
//                switch(state)
//        {
//                case 0 :    PWMA_CCR1 = 5;   break;
//                case 1 :   PWMA_CCR1 = 15;   break;
//                case 2 :    PWMA_CCR1 = 55;   break;
//                case 3 :   PWMA_CCR1 = 250;   break;
//                default:break;

//               
//        }

        }



       
       
       
}



void sys_init(void)
{
        P_SW2=0x80;
       
    P0M0 = 0x00; P0M1 = 0x00;
    P1M0 = 0x00; P1M1 = 0x00;
    P2M0 = 0x00; P2M1 = 0x00;
    P3M0 = 0x00; P3M1 = 0x00;
    P4M0 = 0x00; P4M1 = 0x00;
    P5M0 = 0x00; P5M1 = 0x00;
    P6M0 = 0x00; P6M1 = 0x00;
    P7M0 = 0x00; P7M1 = 0x00;
   
//        P1M0 = 0x00; P1M1 = 0x00;
       

       Timer0_Init();
       
        IT0=1;EX0=1;
        INTCLKO|=0x40;   //EX4=1; 允许INT4外部中断
//        IP2H=0x00;               
        IP2=0x10;

       
        EA=1;                        //打开总中断

}


//// 初始化PWM功能
void PWM_init(void)
{
    CCON = 0x00;
    CMOD = 0x08;
    CL = 0x00;
    CH = 0x00;

    CCAPM1 = 0x42;
    PCA_PWM1 = 0x00;
    CCAP1L = 0x00;                  
    CCAP1H = 0x00;
        CR=1;       
}


void Timer0_Isr(void) interrupt 1
{        
        TL0 = 0xCD;                                //设置定时初始值
        TH0 = 0xD4;                                //设置定时初始值

        if(time>=200)


                switch(dat)
        {       
               
                case 191:IapProgram(EEPROMId+2,dat);break;
                case 121: IapProgram(EEPROMId+2,dat);break;
                case 51: IapProgram(EEPROMId+2,dat);break;
                case 1: IapProgram(EEPROMId+2,dat);break;
                default:IapProgram(EEPROMId+2,191); break;
        }       
       

        if(time<200) time++;
}



void Timer0_Init(void)                //1毫秒@11.0592MHz
{
        AUXR |= 0x80;                        //定时器时钟1T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TMOD |= 0x01;                        //设置定时器模式
        TL0 = 0xCD;                                //设置定时初始值
        TH0 = 0xD4;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}



void INT4_Isr(void) interrupt 16
{
IAP_CONTR=0x60;                       
}


void INT0_Isr(void) interrupt 0
{
//        printf("dat= %bu\r\n",dat);
//        printf("id= %u\r\n",EEPROMId);       
               
}

void delayms(u16 ms)
        {u16 i;
        do{
                i = MAIN_Fosc /10000;
                while(--i);
        }                while(--ms);
}
       










小坤 发表于 2024-8-7 08:13:41

vb2002 发表于 2024-8-7 00:21
电路图
代码我也发出来吧

你这个做个手电,搞出了个文章啦。{:5_322:}

梁工 发表于 2024-8-7 09:47:20

上电时STC-PWM脚位高阻,CN5711的EN也是高阻,所以状态不定,你下拉一个10K电阻就可以解决。

vb2002 发表于 2024-8-7 09:53:20

梁工 发表于 2024-8-7 09:47
上电时STC-PWM脚位高阻,CN5711的EN也是高阻,所以状态不定,你下拉一个10K电阻就可以解决。 ...

那就是开机就拉低电阻,让引脚拉低电平是吗?
回头我试试
页: 1 [2] 3
查看完整版本: 写了个手电的pwm程序,每次上电都会闪一下