数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 2157|回复: 28

求大佬写一个简单的51单片机代码,用来制作充电桩改造的

[复制链接]
发表于 2021-12-29 13:13:04 | 显示全部楼层 |阅读模式
50家元
本帖最后由 浣花洗剑 于 2021-12-30 12:18 编辑

应该很简单,51单片机连接8个按键,io口大佬看心情写,高低电平随意。
这8个按键分别控制7个io口输出,io口随意,高低电平随意。
要求就是1-7号按键分别控制1-7号io口输出,按一下按键延时6小时后恢复,在这6小时期间再次按下重新计时,7路互不干扰,一一对应。
8号按键用来中断所有io口输出。
用来制作充电桩改造的。
12月30日补充:
这个项目是个人研究使用,并不用在商业,虽然我不会写代码,但是我想用在商业的代码恐怕没有这么简单吧。
家里电瓶车比较多,老人年龄大了经常会忘记拔电源线,因此想用个定时的功能,又不想用太多延时继电器,太占空间了,所以才来这发个帖看有没有人能帮忙。


再补充

首先特别感谢各位的回帖,数码之家因你们而精彩。
其次,数码之家本就是志同道合之人交流创作的地方(不包含某两个板块,一不偷二不抢还没有会员费,大家应该能够理解),
每个人都有自己的长处,也有自己不足的复方。我想不必分个三六九等。
知识并不廉价,他的价值并不能以金钱衡量,贴个自己写的代码出来交流学习或者是帮助别人就是对行业的糟践,那GitHub应该彻底灭绝。


发表于 2022-10-14 16:56:43 | 显示全部楼层
原电路里继电器啥的都是按照8A来的
直接改16A很危险
回复

使用道具 举报

发表于 2022-4-27 13:34:09 | 显示全部楼层
本帖最后由 xiaodaishu 于 2022-4-28 15:21 编辑

都是大佬,听说厂家送的8A便携式充电枪可以通过修改程序到16A输出。有大佬编一个程序吗?如下要求:
控制引导线CP,下文用CP替代,是给车辆个1k的PWM波,10%代表8a,20%代表16a,40%代表32a,有兴趣的朋友可以自己写单片机程序,不会玩单片机的可以淘宝买,有卖这个现成的小电路。


https://club.m.autohome.com.cn/bbs/thread/381e5136a62aa6a4/84751286-1.html
https://club.m.autohome.com.cn/bbs/thread/0dcdf5b5d470a155/71543133-1.html
https://club.m.autohome.com.cn/bbs/thread/75009d55a8e7b942/71544117-1.html

https://club.m.autohome.com.cn/bbs/thread/3e5bad9c3def73f5/56836072-1.html

有关PWM的介绍
https://zhuanlan.zhihu.com/p/449960070



回复

使用道具 举报

 楼主| 发表于 2022-1-9 12:38:47 | 显示全部楼层
温力口 发表于 2022-1-9 00:28
51单片机上电复位后,所有I/O口都是高电平状态,如果你要高电平有效,复位后首先要把相关的I/O置零,即使 ...

十分感谢,最近在学习简单的编程
回复

使用道具 举报

发表于 2022-1-9 00:28:39 | 显示全部楼层
浣花洗剑 发表于 2022-1-8 23:01
有个疑问再麻烦大佬一下,如果我想输入高电平有效,就是按键高电平有效应该怎么改代码呢 ...

51单片机上电复位后,所有I/O口都是高电平状态,如果你要高电平有效,复位后首先要把相关的I/O置零,即使这样,这I/O口还是有一个短暂的高脉冲输出,对于某些场合,这是不允许的。这样吧,我明晚弄个给你参考下。
回复

使用道具 举报

 楼主| 发表于 2022-1-8 23:01:19 来自手机浏览器 | 显示全部楼层
温力口 发表于 2022-1-3 20:37
折腾的不错,恭喜成功!

有个疑问再麻烦大佬一下,如果我想输入高电平有效,就是按键高电平有效应该怎么改代码呢
回复

使用道具 举报

发表于 2022-1-3 20:37:40 | 显示全部楼层
浣花洗剑 发表于 2022-1-3 13:41
case 0xfe:time1=time_set;break;
                case 0xfd:time2=time_set;break;
   ...

折腾的不错,恭喜成功!
回复

使用道具 举报

 楼主| 发表于 2022-1-3 13:41:48 | 显示全部楼层
温力口 发表于 2021-12-30 10:59
早上闲来无事,也来码几行玩玩。
//MCU:STC90C52RC
//时钟:12MHz晶振

                case 0xfe:time1=time_set;break;
                case 0xfd:time2=time_set;break;
                case 0xfc:time3=time_set;break;
                case 0xfb:time4=time_set;break;
                case 0xf7:time5=time_set;break;
                case 0xef:time6=time_set;break;
                case 0xdf:time7=time_set;break;
                case 0x7f:key_out=0xff;break;


0xfc应该是fb吧? 我百度了下二进制改十六进制,摸索着改了下。没改之前测试P2^3输出不正常,改成下面这样就正常了。对了,我还增加了一路,复位按钮直接RST代替了。
{
                case 0xfe:time1=time_set;break;
                case 0xfd:time2=time_set;break;
                case 0xfb:time3=time_set;break;
                case 0xf7:time4=time_set;break;
                case 0xef:time5=time_set;break;
                case 0xdf:time6=time_set;break;
                case 0xbf:time7=time_set;break;
                case 0x7f:time8=time_set;break;
                default: break;
        }
}

现在全文是这样,问号是字体问题,懒得改了。
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define key_bord P1         //P1^0~P1^6??1~7#?,P1^7?8#?,??????
#define key_out P0         //P2^0~P2^6??1~7#?????,??????

uint time1,time2,time3,time4,time5,time6,time7,time8;        //1~7#?????????
uint time_set=6;       //6??????

void InitTimer0(void)       //8?????,250?????
{
    TMOD = 0x02;
    TH0 = 0x00;
    TL0 = 0x06;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}

void timer0() interrupt 1    //???0????,8??????
{
        uchar i,k;
        i++;
        if(i==200)      //200*250=50000??=50???
        {
                i=0;
                k++;
        }
        if(k==20)      //20*50??=1??
        {
                k=0;
                if(time1)time1--;     //?1??????
                        else key_out|=0x01;
                if(time2)time2--;     //?1??????
                        else key_out|=0x02;
                if(time3)time3--;     //?1??????
                        else key_out|=0x04;
                if(time4)time4--;     //?1??????
                        else key_out|=0x08;
                if(time5)time5--;     //?1??????
                        else key_out|=0x10;
                if(time6)time6--;     //?1??????
                        else key_out|=0x20;
                if(time7)time7--;     //?1??????
                        else key_out|=0x40;
                                              if(time8)time8--;     //?1??????
                        else key_out|=0x80;
        }
}

void key_scan(void)       //??????
{
        if(key_bord!=0xff)      //???????
        {
                key_out&=key_bord;    //??????,????????,???????P2?,?????????
        }
        switch(key_bord)
        {
                case 0xfe:time1=time_set;break;
                case 0xfd:time2=time_set;break;
                case 0xfb:time3=time_set;break;
                case 0xf7:time4=time_set;break;
                case 0xef:time5=time_set;break;
                case 0xdf:time6=time_set;break;
                case 0xbf:time7=time_set;break;
                case 0x7f:time8=time_set;break;
                default: break;
        }
}

void main(void)
{
        InitTimer0();
        while(1)
        {               
                key_scan();
        }               
}


回复

使用道具 举报

发表于 2021-12-30 13:55:49 | 显示全部楼层
温力口 发表于 2021-12-30 12:39
哈哈,给第一个吧,我M币好多。

10万M币
回复

使用道具 举报

发表于 2021-12-30 12:39:06 | 显示全部楼层
浣花洗剑 发表于 2021-12-30 11:59
十分感谢您的回帖,看您更不差MB,就给了第一个人,大佬牛逼。

哈哈,给第一个吧,我M币好多。
回复

使用道具 举报

 楼主| 发表于 2021-12-30 11:59:55 | 显示全部楼层
温力口 发表于 2021-12-30 10:59
早上闲来无事,也来码几行玩玩。
//MCU:STC90C52RC
//时钟:12MHz晶振

十分感谢您的回帖,看您更不差MB,就给了第一个人,大佬牛逼。
回复

使用道具 举报

 楼主| 发表于 2021-12-30 11:58:21 | 显示全部楼层
t3486784401 发表于 2021-12-30 09:03
大早上的仿真一把吧,标准 2051 跑 12M 就行,P3 一侧接按键,P1 一侧接输出,都是低电平有效。

改成了 3s ...

十分感谢,十分感谢您的回帖。
看您也不差mb,就给了第一个人,希望您能够谅解。
回复

使用道具 举报

发表于 2021-12-30 10:59:45 | 显示全部楼层
本帖最后由 温力口 于 2021-12-30 11:04 编辑

早上闲来无事,也来码几行玩玩。
//MCU:STC90C52RC
//时钟:12MHz晶振

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define key_bord P1         //P1^0~P1^6对应1~7#键,P1^7为8#键,低电平有效。
#define key_out P2          //P2^0~P2^6对应1~7#键的输出端,低电平有效。

uint time1,time2,time3,time4,time5,time6,time7;       //1~7#键对应的时间变量。
uint time_set=60*60*6;       //6小时的秒数。

void InitTimer0(void)       //8位自动重装,250微秒定时。
{
    TMOD = 0x02;
    TH0 = 0x00;
    TL0 = 0x06;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}

void timer0() interrupt 1    //定时器0中断函数,8位自动重装。
{
        uchar i,k;
        i++;
        if(i==200)      //200*250=50000微秒=50毫秒。
        {
                i=0;
                k++;
        }
        if(k==20)      //20*50毫秒=1秒。
        {
                k=0;
                if(time1)time1--;     //每1秒累减一次。
                        else key_out|=0x01;
                if(time2)time2--;     //每1秒累减一次。
                        else key_out|=0x02;
                if(time3)time3--;     //每1秒累减一次。
                        else key_out|=0x04;
                if(time4)time4--;     //每1秒累减一次。
                        else key_out|=0x08;
                if(time5)time5--;     //每1秒累减一次。
                        else key_out|=0x10;
                if(time6)time6--;     //每1秒累减一次。
                        else key_out|=0x20;
                if(time7)time7--;     //每1秒累减一次。
                        else key_out|=0x40;
        }
}

void key_scan(void)       //按键扫描函数
{
        if(key_bord!=0xff)      //当有按键按下。
        {
                key_out&=key_bord;    //不用延时检测,直接读出键盘状态,并将该状态送到P2口,控制继电器的通断。
        }
        switch(key_bord)
        {
                case 0xfe:time1=time_set;break;
                case 0xfd:time2=time_set;break;
                case 0xfc:time3=time_set;break;
                case 0xfb:time4=time_set;break;
                case 0xf7:time5=time_set;break;
                case 0xef:time6=time_set;break;
                case 0xdf:time7=time_set;break;
                case 0x7f:key_out=0xff;break;
                default: break;
        }
}

void main(void)
{
        InitTimer0();
        while(1)
        {               
                key_scan();
        }               
}

回复

使用道具 举报

发表于 2021-12-30 09:24:25 | 显示全部楼层
本帖最后由 chunlei233 于 2021-12-30 09:37 编辑
高级会员 发表于 2021-12-29 14:54
知识和技术什么时候这么贱价了?

赞同!有些人就是"贱人贱己贱行业",代码写的不咋地,还好意思贴出来!再说,有没有考虑,突然断电再恢复的情况?
回复

使用道具 举报

发表于 2021-12-30 09:20:50 | 显示全部楼层
t3486784401 发表于 2021-12-30 00:33
整体逻辑没毛病,但不加临界区真的没问题么...

CountTab 在 main 第 56 行写入 6小时倒计时初值(ms), ...

经验丰富,向您学习。
回复

使用道具 举报

发表于 2021-12-30 09:03:01 | 显示全部楼层
大早上的仿真一把吧,标准 2051 跑 12M 就行,P3 一侧接按键,P1 一侧接输出,都是低电平有效。

改成了 3s 演示可重复触发的单稳态;



代码直接贴吧,感觉发工程包也下不起......  未使用中断,简单三个非阻塞任务就能完成:

  1. #include "reg2051.h"

  2. // Keys  : P3.0~5,7, L=Pressed
  3. // Relays: P1.0~6, L=Active

  4. void main(void)
  5. {
  6.     unsigned char i, key;
  7.     unsigned char ReqSet, ReqReset;     // b6:0 = SetON/SetOFF Request
  8.     unsigned long ArrCnt[7]= {0};       // [6:0]= Virtual Timer

  9.     // IO Init
  10.     P1= 0xFF;
  11.     P3= 0xFF;
  12.     // T0 Init: 16bit FreeRun
  13.     TR0 = 0;
  14.     TMOD= 0x01;     // T0: 16bit
  15.     TL0 = 0;        // N=64K
  16.     TH0 = 0;        // N=64K
  17.     IT0 = 0;
  18.     TF0 = 0;
  19.     TR0 = 1;        // Start T0

  20.     // Main Loop
  21.     EA= 0;
  22.     while(1)
  23.     {      
  24.         // TimeBase Proc
  25.         if(TF0)
  26.         {
  27.             // 1M/64k= 15.26Hz
  28.             for(i=0; i<7; i++)
  29.             {
  30.                 if(ArrCnt[i]>0)
  31.                 {
  32.                     ArrCnt[i]--;
  33.                     if(ArrCnt[i]==0)
  34.                         ReqReset|= 0x1<<i;
  35.                 }
  36.             }
  37.             TF0= 0;
  38.         }

  39.         // Relay Proc
  40.         if(ReqSet>0)
  41.         {
  42.             P1&= ~ReqSet;           // Set ON(=L) at P1[6:0]
  43.             ReqSet= 0;
  44.         }
  45.         if(ReqReset>0)
  46.         {
  47.             P1|= ReqReset;          // Set OFF(=H) at P1[6:0]
  48.             ReqReset= 0;
  49.         }

  50.         // Key Proc
  51.         key= ~P3;                           // Read Keys from P3[7,5:0]
  52.         key= (key&0x80)>>1 | (key&0x3F);    // key[6:0], H=Active
  53.         if(key)
  54.         {
  55.             // Key Pressed
  56.             for(i=0; i<7; i++)
  57.             {
  58.                 if( key&(0x1<<i) )
  59.                 {
  60.                     ReqSet|= 0x1<<i;        // Request to turn ON
  61.                     ArrCnt[i]= 329616L;     // Ton= N/15.26 (s)
  62.                 }
  63.             }
  64.         }

  65.         // Other Non-blocking Proc
  66.     }
  67. }
复制代码




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复

使用道具 举报

发表于 2021-12-30 09:01:53 | 显示全部楼层
t3486784401 发表于 2021-12-30 00:33
整体逻辑没毛病,但不加临界区真的没问题么...

CountTab 在 main 第 56 行写入 6小时倒计时初值(ms), ...

马上加上!!!
回复

使用道具 举报

发表于 2021-12-30 00:33:06 | 显示全部楼层
上官梦舞 发表于 2021-12-29 15:15
使用stc15w408as单片机 sop20脚
P3接按键,可以接8个,P1口控制继电器,低电平是关闭
关闭按键 接在复位脚 哈 ...


整体逻辑没毛病,但不加临界区真的没问题么...

CountTab 在 main 第 56 行写入 6小时倒计时初值(ms),在 tm0_isr 当中递减。

考虑到是 32bit 变量,你在 main() 当中写一半发生中断就悲剧了,可能造成定时不足。
建议在第 50 行加入 EA=0 锁定临界区,然后再在第 60 行 EA=1 释放临界区。
回复

使用道具 举报

发表于 2021-12-29 18:46:03 | 显示全部楼层
上官梦舞 发表于 2021-12-29 15:15
使用stc15w408as单片机 sop20脚
P3接按键,可以接8个,P1口控制继电器,低电平是关闭
关闭按键 接在复位脚 哈 ...

好评好评。给服务器上税了。
回复

使用道具 举报

发表于 2021-12-29 17:32:32 | 显示全部楼层
haisens 发表于 2021-12-29 15:42
我点了,扣了55M币

恭喜你,给服务器交税了,上面已经是全部代码,只是下载了工程文件而已。
回复

使用道具 举报

发表于 2021-12-29 16:27:27 | 显示全部楼层
IO驱动什么呢?还要加驱动电路吧。
这要求弄个简单的PLC更容易实现。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-8-11 11:16 , Processed in 0.109201 second(s), 9 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表