2

关于投票
体彩随机摇奖源代码(36选7为例)---程序+注释

体彩随机摇奖源代码(36选7为例)

/*从一组n项的数组中随机抽了不同的m项(m<=n)*/

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <time.h>

#define n 36

#define m 7

int main( void )

{

 int i, j, logic, a[ m ];                /*把随机数保存到a[m]*/                       

 srand( time( NULL ) );        /*取得时间*/

 for ( i = 0; i < m; i++ ){

   do  {          /*新产生的随机数与a[m]中的每项进行比较*/

       logic = 0;

       a[ i ] = rand( ) % n + 1;    /*产生1~n范围的随机数*/

       for( j = 0; j < i ; j++) {

           if( a[ j ] == a[ i ] ) {

                  logic = 1;         /*随机数与a[m]中的相同*/

                  break;

             }

       }/* end for */

   }while( logic );

   printf( "%d ", a[ i ] );

   }/* end for*/

   return 0;

}/* end main */

写好的EXE程序,可以直接运行

rar

系统分类: 单片机
用户分类: 单片机
标签: C51 体彩 随机摇奖 源代码(
来源: 原创
发表评论 阅读全文(280) | 回复(2)

3

关于投票
51单片机的FIFO(先入先出)循环队列实现(已在串口通信中实际应用)

51单片机的FIFO(先入先出)循环队列实现

//////////////////////////////////////////////////////////
// 文件:config.h
//////////////////////////////////////////////////////////
#ifndef __CONFIG_H
#define __CONFIG_H
//这一段无需改动
//This segment should not be modified
#ifndef TRUE
#define TRUE  1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef unsigned char  uint8;                   /* defined for unsigned 8-bits integer variable  无符号8位整型变量  */
typedef signed   char  int8;                    /* defined for signed 8-bits integer variable  有符号8位整型变量  */
typedef unsigned short uint16;                  /* defined for unsigned 16-bits integer variable  无符号16位整型变量 */
typedef signed   short int16;                   /* defined for signed 16-bits integer variable   有符号16位整型变量 */
typedef unsigned int   uint32;                  /* defined for unsigned 32-bits integer variable  无符号32位整型变量 */
typedef signed   int   int32;                   /* defined for signed 32-bits integer variable   有符号32位整型变量 */
typedef float          fp32;                    /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */

#i nclude "FIFOQUEUE.h"
#endif
 
 
 
 
//////////////////////////////////////////////////////////
// 文件:FIFOQUEUE.h
//////////////////////////////////////////////////////////
#ifndef _FIFOQUEUE_H
#define _FIFOQUEUE_H
#define ElemType       uint8
#define QueueSize      20
#define QueueFull      0
#define QueueEmpty     1
#define QueueOperateOk 2
struct FifoQueue
{
    uint16 front;
    uint16 rear;
    uint16 count;
    ElemType dat[QueueSize];
};
//Queue Initalize
extern void QueueInit(struct FifoQueue *Queue);
// Queue In
extern uint8 QueueIn(struct FifoQueue *Queue,ElemType sdat);
// Queue Out
extern uint8 QueueOut(struct FifoQueue *Queue,ElemType *sdat);
#endif
 
 
 
//////////////////////////////////////////////////////////
// 文件:FIFOQUEUE.C
//////////////////////////////////////////////////////////
#i nclude "config.h"
//Queue Init
void QueueInit(struct FifoQueue *Queue)
{
    Queue->front = Queue->rear;
    Queue->count = 0;
}
// Queue In
uint8 QueueIn(struct FifoQueue *Queue,ElemType sdat)
{
    if((Queue->front == Queue->rear) && (Queue->count == QueueSize))
    {                    // full
        return QueueFull;
    }else
    {                    // in
        Queue->dat[Queue->rear] = sdat;
        Queue->rear = (Queue->rear + 1) % QueueSize;
        Queue->count = Queue->count + 1;
        return QueueOperateOk;
    }
}
// Queue Out
uint8 QueueOut(struct FifoQueue *Queue,ElemType *sdat)
{
    if((Queue->front == Queue->rear) && (Queue->count == 0))
    {                    // empty
        return QueueEmpty;
    }else
    {                    // out
        *sdat = Queue->dat[Queue->front];
        Queue->front = (Queue->front + 1) % QueueSize;
        Queue->count = Queue->count - 1;
        return QueueOperateOk;
    }
}
 
 
 
//////////////////////////////////////////////////////////
// 文件:Main.C
//////////////////////////////////////////////////////////
#i nclude <reg52.h>
#i nclude "config.h"
void main(void)
{
    struct FifoQueue MyQueue;
    ElemType sh;
    uint8 i;
    QueueInit(&MyQueue);
    while(1)
    {
        for(i = 0;i < 30;i++)
        {
            if(QueueIn(&MyQueue,i) == QueueFull) break;
        }
        for(i = 0;i < 30;i++)
        {
            if(QueueOut(&MyQueue,&sh) == QueueEmpty) break;
        }
    }
    while(1);
}
 
作者说明:[原创]此程序在51上实现,很多个项目都用到,调试通过,做串口的FIFO很合适......
 
看完了要哈~~~
系统分类: 单片机
用户分类: 单片机
标签: 51 单片机 FIFO 先入先出 循环 队列
来源: 原创
发表评论 阅读全文(619) | 回复(1)

3

关于投票
电子密码锁源程序---汇编

电子密码锁源程序---汇编

摘要:本系统由单片机系统、矩阵键盘、LED显示和报警系统组成。系统能完成开锁、超时报警、超次锁定、管理员解密、修改用户密码基本的密码锁的功能。除上述基本的密码锁功能外,还具有调电存储、声光提示等功能,依据实际的情况还可以添加遥控功能。本系统成本低廉,功能实用

关键词:AT89S51;AT24C02;电子密码锁;矩阵键盘

        ;********************************************
        ;*********        电子密码锁        *********
        ;********************************************
        ;*********        2005/12/24        *********
        ;********************************************
        ;显示缓冲区
        ;LED1    EQU    6FH
        BUFF    EQU    6EH
        TIMERS1 EQU    6DH     ;输入回车的次数
        TIMERS2 EQU    6CH     ;报警的次数
        TIMERS  EQU    6BH     ;输入数字的位数
        ;LED6  EQU    6AH
        ;密码缓冲区
        PS1   EQU    69H
        PS2   EQU    68H
        PS3   EQU    67H
        PS4   EQU    66H
        PS5   EQU    65H
        PS6   EQU    64H
        ;AT24C02读取缓冲区
        AT1   EQU    63H
        AT2   EQU    62H
        AT3   EQU    61H
        AT4   EQU    60H
        AT5   EQU    5FH
        AT6   EQU    5EH
        ;按键标志位
        F_1   BIT   20H
        F_2   BIT   21H
        F_3   BIT   22H
        F_4   BIT   23H
        BUF_FULL BIT 24H    ;密码已经够六位的标志位,为1表示满
        CH_STATE BIT 25H    ;系统更改的状态标志位,为1表示busy
        FLAG1 BIT    26H    ;功能键标志位,为1表示功能按键。
        F_F1  BIT    27H
        F_F2  BIT    28H
        PSW_F BIT    29H    ;密码是否正确的标志位
        ;口资源定义
        SPK   BIT    P2.1
        JDQ   BIT    P2.3
        SDA   BIT    P2.4   ;定义串口数据端
        SCL   BIT    P2.5
        ;发光二极管灯
        L1    BIT    P1.0
        L2    BIT    P1.1
        L3    BIT    P1.2
        ;
        ORG   0000H
        AJMP  MAIN
        ORG   000BH
        ;AJMP  TIMER0
        ORG   001BH
        ;AJMP  TIMER1
        ORG   0030H
   MAIN:MOV   SP,    #70H
        MOV   TMOD,  #11H
        MOV   TH0,   #3CH
        MOV   TL0,   #0B0H
        MOV   TH1,   #3CH
        MOV   TL1,   #0B0H
        CLR   F_1             ;清除标志位
        CLR   F_2
        CLR   F_3
        CLR   F_4
        CLR   BUF_FULL
        CLR   CH_STATE
        CLR   FLAG1
        CLR   F_F1
        CLR   F_F2
        CLR   PSW_F
        MOV   BUFF,#00H        ;调用
        LCALL INITPS           ;初始化环境
        LCALL INITAT
        LCALL  XSA            ;调用默认显示
        MOV    TIMERS1,#00H
        NOP
        MOV   PS1,  #11H     ;初始化密码830620
        MOV   PS2,  #0AH
        MOV   PS3,  #02H
        MOV   PS4,  #13H
        MOV   PS5,  #0BH
        MOV   PS6,  #02H
  START:NOP                  ;程序开始
        LCALL CH_KEY         ;检查键盘
        AJMP  START          ;返回

 CH_KEY:LCALL KS             ;检查有没有按键按下
        JNZ   LK1
        AJMP  CH_KEY
    LK1:
        LCALL T12MS
        ACALL KS
        JNZ   LK2
        RET

    LK2:
        NOP
        LCALL SBIE            ;按键识别子程序
        MOV   BUFF,  A        ;送缓冲区以识别是数字键还是功能键?
        LCALL CH_KF           ;判断按键功能。
        JB    FLAG1  ,KEY_FUN ;标志为1,则为功能键
;***********数字按键输入并且存放到缓冲区内等待比较***********
KEY_DIG:NOP                   ;设一标志,辨别输入是否满
        ;SETB  TR0
        INC   TIMERS          ;输入数字的位数
        MOV   A,    TIMERS
        CLR   C
        SUBB  A,    #01H
        JNZ   PS_2
        MOV   PS1,  BUFF         ;依照顺序存放密码
        AJMP  NEXT
   PS_2:MOV   A,   TIMERS
        SUBB  A,    #02H
        CLR   C
        JNZ   PS_3
        MOV   PS2,   BUFF
        AJMP  NEXT
   PS_3:MOV   A,   TIMERS
        CLR   C
        SUBB  A,    #03H
        JNZ   PS_4
        MOV   PS3,   BUFF
        AJMP  NEXT
   PS_4:MOV   A,    TIMERS
        CLR   C
        SUBB  A,    #04
        JNZ   PS_5
        MOV   PS4,  BUFF
        AJMP  NEXT
   PS_5:MOV   A,    TIMERS
        CLR   C
        SUBB  A,    #05
        JNZ   PS_6
        MOV   PS5,  BUFF
        AJMP  NEXT
   PS_6:MOV   A,    TIMERS
        CLR   C
        SUBB  A,    #06H
        JNZ   CH_KEY
        MOV   PS6,  BUFF
   NEXT:LCALL XSC
        MOV   R7,   TIMERS    ;比较输入的次数。
        CJNE  R7,   #06H  ,FULL
   FULL:JC    NEXT9
        SETB  BUF_FULL
        MOV   TIMERS,#06H
        CLR   L3
        NOP
        CLR   P2.1
        LCALL T100MSD
        SETB  P2.1
        NOP
        AJMP  CH_KEY
  NEXT9:CLR   P2.1            ;密码输入一位,鸣叫一声。
        CLR   L3
        LCALL T100MSD         ;延时100ms
        SETB  L3
        SETB  P2.1
        AJMP  CH_KEY
;*****************功能按键比较并且跳转*************
KEY_FUN:
        CLR   FLAG1
        CLR   C
        MOV   A,   BUFF
        SUBB  A,   #03H     ;按键CL跳转
        JNZ   EN_C
        AJMP  CL
   EN_C:CLR   C
        MOV   A,   BUFF     ;按键EN跳转
        SUBB  A,   #00H
        JNZ   F1_C
        AJMP  EN
   F1_C:CLR   C
        MOV   A,   BUFF
        SUBB  A,   #1BH
        JNZ   F2_C
        AJMP  FU1
   F2_C:CLR   C
        MOV   A,   BUFF
        SUBB  A,   #1AH
        JNZ   F3_C
        AJMP  FU2
   F3_C:CLR   C
        MOV   A,   BUFF
        SUBB  A,   #19H
        JNZ   F4_C
        AJMP  FU3
   F4_C:CLR   C
        MOV   A,   BUFF
        SUBB  A,   #18H
        JZ    FU4
  EXIT8:NOP
        LJMP  CH_KEY
;***************开门子程序 ********************************
     CL:NOP
        SETB  L3
        MOV   BUFF, #00H             ;消密码缓冲
        MOV   TIMERS,#00H
        LCALL INITPS              ;消除AT缓冲,加调电存储后一定要加上
        LCALL XSC
        LCALL BP
        LCALL BP
        LCALL T100MSD
        LCALL BP
        CLR   FLAG1
        AJMP  CH_KEY

    FU4:NOP
        LCALL BP
        LCALL T100MSD
        LCALL BP
        LCALL T100MSD
        LCALL BP
        LCALL T100MSD
        LCALL BP
        LCALL T100MSD
        LCALL BP
        CLR   FLAG1
        AJMP  CH_KEY

    FU3:NOP
        LCALL BP
        LCALL T100MSD
        LCALL BP
        LCALL KILLXS ;关闭显示
        CLR   FLAG1
        AJMP  CH_KEY

    FU1:NOP
        LCALL XSC
        JB    F_F1,   NEXT_F1
        CLR   L1
        LCALL BP
        SETB  F_F1
        AJMP  CH_KEY
NEXT_F1:SETB  L1
        LCALL BP
        CLR   F_F1
        ;LCALL CH_STATE            ;查看现在的状态以防误按
        ;SETB  TR1                ;报警限制暂时不开
        ;INC   F_F1
        CLR    FLAG1
        AJMP  CH_KEY

    FU2:NOP
        JB    F_F2,   NEXT_F2
        CLR   L2
        LCALL BP
        SETB  F_F2
        AJMP  CH_KEY
NEXT_F2:SETB  L2
        LCALL BP
        CLR   F_F2
        CLR   FLAG1
        AJMP  CH_KEY
;***************按键的功能描述*************************
     EN:NOP
        JB    BUF_FULL,   GOON
        AJMP  EXIT
   GOON:CLR   BUF_FULL
        JB    F_F2, AT_WRON             ;F2按键标志,若为1,则调用修改密码子程序。
        LCALL AT_RADE
        LCALL C_PSW                  ;比较密码子程序
        JB    PSW_F,OPEN             ;密码比较正确,则调用开锁子程序
        LCALL XSD
        INC   TIMERS2
        MOV   R7,TIMERS2            ;密码错误,调入输入密码输入次数,准备锁定键盘
        CJNE  R7,#03H,D0
     D0:JC    NEXT1                 ;错误次数小3次
        LCALL XSE               ;锁定5分钟
        LCALL WARN2S
        LCALL LOCK_1M
  NEXT1:LCALL WARN2S            ;报警2分钟
        LCALL XSA
   EXIT:LCALL INITPS
        MOV   BUFF,   #00H
        CLR   FLAG1
        MOV   TIMERS, #00H
        AJMP  CH_KEY                 ;跳出
       
AT_WRON:LCALL AT_WR
        LCALL XSF
        LCALL BP
        LCALL T100MSD
        LCALL BP
        LCALL T500MSD
        LCALL KILLXS
        LCALL T500MSD
        LCALL XSF
        LCALL T500MSD
        LCALL KILLXS
        LCALL T500MSD
        LCALL XSF
        LCALL T500MSD
        NOP
        NOP
        LCALL XSA
        AJMP  EXIT

     OPEN:MOV  A,     TIMERS1
         CJNE A,     #09H,CLT1
    CLT1:JC   GOON1
         MOV  TIMERS1,#00H
   GOON1:INC  TIMERS1                ;输入回车的次数
         MOV  TIMERS2,#00H
         SETB  L3
         CLR   PSW_F
         LCALL XSB
         CLR  JDQ             ;开门
         LCALL BP
         LCALL BP
         LCALL BP
         LCALL BP
         LCALL SEC
         LCALL SEC
         LCALL SEC
         LCALL SEC
         LCALL SEC
         LCALL SEC
         LCALL SEC
         LCALL SEC
         SETB  JDQ
         LCALL XSA
         NOP
         AJMP  EXIT


;**************各类子程序********************************
;****  注意清楚缓冲区时AT1...AT6不应在初始化中执行,以 ***
;****  防两缓冲区都为0,相同开锁                       ***
;********************************************************

CLR_BUF:MOV   R7,   #06H
        MOV   R0,  #6FH
  LOOP1:MOV   A,   #00H
        MOV   @R0, A
        DEC   R0
        DJNZ  R7,LOOP1
        RET
;*************初始化显示缓冲区以及其他缓冲区**************
 INITPS:PUSH  ACC
        PUSH  PSW
        MOV   R7,  #06H
        MOV   R1,  #PS1
        MOV   A,   #00H
INIT_PS:MOV   @R1, A
        DEC   R1
        DJNZ  R7,  INIT_PS
        POP   PSW
        POP   ACC
        NOP
        RET

 INITAT:PUSH  ACC
        PUSH  PSW
        MOV   R7,#06H
        MOV   R1,#AT1
        MOV   A, #00H
INIT_AT:MOV   @R1, A
        DEC   R1
        DJNZ  R7,  INIT_AT
        MOV   TIMERS,#00H     ;密码输入的次数清零。
        POP   PSW
        POP   ACC
        RET

;*************  按键识别子程序  ***************************
   SBIE:MOV   R2,   #0EFH      ;识别按键子程序,数据送A保存,课本P146页。
        MOV   R4,   #00H
    LK4:MOV   A,    R2
        MOV   P0,   A
        NOP
        MOV   A,    P0
        JB    ACC.0,LONE
        MOV   A,    #00H
        AJMP  LKP
   LONE:JB    ACC.1,LTWO
        MOV   A,    #08H
        AJMP  LKP
   LTWO:JB    ACC.2,LTHR
        MOV   A,   #10H
        AJMP  LKP
   LTHR:JB    ACC.3,NEXTT     ;判断下一列
        MOV   A,   #18H
    LKP:ADD   A,   R4
        PUSH  ACC
    LK3:ACALL KS
        JNZ   LK3
        POP   ACC
        RET
  NEXTT:INC   R4
        MOV   A,   R2
        JNB   ACC.7,KND
        RL    A
        MOV   R2,  A
        AJMP  LK4
    KND:AJMP  CH_KEY

     KS:MOV   P0,    #0FH
        NOP
        MOV   A,     P0
        CPL   A
        ANL   A,     #0FH
        NOP
        RET

  CH_KF:CLR   C
        MOV   A,   BUFF       ;判断是数字按键还是功能按键,为1表示功能键
        CJNE  A,   #17H,  KY
     KY:JC    SET_CH         ;假若是数字按键则标志置为0
        SETB  FLAG1          ;假若是功能按键则标志置为1
        AJMP  CHKE_END
 SET_CH:CLR   C
        MOV   A,   BUFF
        SUBB  A,   #00H
        JNZ   EN_CH
        SETB  FLAG1
        AJMP  CH_END
  EN_CH:MOV   A,   BUFF
        SUBB  A,   #03H
        JNZ   DIG
        SETB  FLAG1
        AJMP  CH_END
    DIG:CLR   FLAG1
 CH_END:NOP
CHKE_END:RET

   T12MS:MOV     R7,   #18H
     TM1:MOV     R6,   #0FFH
    TM66:DJNZ    R6,   TM66
         DJNZ    R7,   TM1
         RET

;****************检验密码正误******************************
   C_PSW:PUSH  PSW
         PUSH  ACC
         MOV  R2,#06H
         MOV  R0,#PS1
         MOV  R1,#AT1
     C_P:CLR  C
         MOV  A,@R0
         SUBB A,@R1
         JNZ  RETURN
         DEC  R0
         DEC  R1
         DJNZ R2,C_P
         NOP
         SETB PSW_F
         AJMP EXIT7
  RETURN:CLR  PSW_F
   EXIT7:NOP
         POP  ACC
         POP  PSW
         RET
;×××××××××××××××××锁定,鸣笛子程序××××××××××××
 LOCK_1M:MOV  R4,#3CH                   ;锁定1分钟
 M1_LOOP:LCALL SEC
         DJNZ  R4,M1_LOOP
         NOP
         RET

    WARN2S:PUSH  PSW
          PUSH  ACC
          MOV   R5, #14H      ;调用20次BP,报警2s
     WARN:LCALL BP
          DJNZ  R5,WARN
          NOP
          POP   ACC
          POP   PSW
          NOP
          RET
      BP:CLR   SPK            ;鸣笛子程序
         LCALL T100MSD
         SETB  SPK
         NOP
         RET

看完了要

系统分类: 单片机
用户分类: 单片机
标签: 电子密码锁 源程序 汇编
来源: 原创
发表评论 阅读全文(241) | 回复(1)

2

关于投票
软件模拟串口程序(转)没有双串口单片机的福音

软件模拟串口程序(转)

找个双串口单片机真是麻烦,所以想做个软件串口玩玩

环境:
winAVR
M48,8MHz
9600,1,8,1

输出:用定时器控制普通IO口输出位
输入:用外部中断+定时器,判断位的宽度

好几天没休息好了,利用闲暇写的,也没找到别人的参考程序,不过终于算是可以工作了,其实还应该有很多其它的方法可以试一下,比如用PWM输出串行数据,用输入捕获接收数据,或定时查询,或用任意一个IO口中断,则每个引脚都有可能

现在还有些问题,全双工同时收发时发送偶尔出错,别的中断干扰所致吧,占用两个定时器有些浪费,以后再修改吧,最好加上各种波率。软件串口终究不如原串口好用,不过要求不苛刻的话可以一用,如果波特率改到4800应该会稳定许多

本程序为直接摘出部分,删了无关的部分,在此可能有些变量没用,或有段落遗漏,请谅

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/wdt.h>

#define Sbit1() PORTD|=1<<PD1
#define Sbit0() PORTD&=~(1<<PD1)


volatile unsigned int
eep_ms,//毫秒计时
keytime,                    //等待时间
SoundOnTime;                    ////
volatile unsigned  char
rdata,
key,
start=0,
keycode,        //
*TxPoint,
rtime,
INT0_time,                //中断次数

RxLength=0,        //接收长度
RUDR,            //摸拟串口接收的数据
TxLength,                    //串口发送数据长度
SUDR;                        //串口发送的数据

unsigned char arr[10],DispBuff[10];


void Initial_IO(void)//IO口初始化
    {
     DDRD = 0X82;              //PD1串口输出,PD0串口输入,PD2模拟串口输入(INT0)
     PORTD = 0X82;             //PD1输出高电平
    }

void Initial_INT0(void)
    {
    EICRA|=(1<<ISC00);//边沿触发
     EIMSK|=1<<INT0;
    }

void Initial_timer0(void)                         //定时器0初始化
    {
     TCCR0B|=(1<<CS01);                           //定时器0:8M/8分频
     TIMSK0|=(1<<TOIE0);
    }

void Initial_timer1(void)
    {
     TCCR1A=(1<<WGM11);                   
          TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS11); //定时器1 频率1MHz
     ICR1=1000;
     TIMSK1|=(1<<TOIE1);
    }

void Initial_timer2(void)
    {
     TCCR2B=(1<<CS22); //系统频率/64分频,8us
     TIMSK2|=(1<<TOIE2);                                    //中断允许
    }


void Initial_WDR(void)                                       //看门狗初始化
    {
    wdt_enable(WDTO_1S);
    wdt_reset();
    }


void Initial(void)
{
    Initial_IO();
    Initial_timer0();
    Initial_timer1();
    Initial_timer2();
    Initial_INT0();
    Initial_WDR();
    sei();
}


/*启动串口发送*/
void SendData(unsigned char *P,unsigned char DataLength)
    {
    TxLength="DataLength";
    TxPoint="P";
    start="0";
    }
   

int main (void)
    {

    Initial();

    while(1)
        {
        wdt_reset();
        if((rdata)&&(eep_ms>10))//收到数据延时10mS后启动发送,回送验证数据
            {
            key="0";
            SendData(&DispBuff[0],9);//发送DispBuff[0]的9位数据
            while(TxLength);//等待发送完成
            rdata="0";
            eep_ms=0;
            }
        }
    }


/*定时器0,100us溢出中断*/
SIGNAL(SIG_OVERFLOW0)
    {
    TCNT0=151;//重载数据,计时区间为151---255,共104uS,一个位的时间
    if(TxLength)//
        {
        if(start==0)
            {
            Sbit0();//起始位
            SUDR=*(TxPoint++);
            }
        else
            {
            if((start<=8))
                {
                if(SUDR&(1<<(start-1)))Sbit1();//数据1
                else Sbit0();//数据0
                }
            else Sbit1();//停止位
            }
        if(start<10)start++;
        else
            {
            TxLength--;//一字节 发送完成,字节数减1
            start="0";
            }//
        }
    }

/*定时器1,1ms溢出中断*/
SIGNAL(SIG_OVERFLOW1)
{
    eep_ms++;
}
/*定时器2*/
SIGNAL(SIG_OVERFLOW2)
    {
    sei();   
    if(INT0_time)//有数据
        {
        INT0_time=0;//中断次数清0
        rdata="1";//置有数据标志
        eep_ms=0;
        if(RxLength<10)DispBuff[RxLength++]=RUDR;
       
        }
    if(rtime<4)rtime++;//字节间隔时间,间隔3个字节重新开始一帧
    else RxLength="0";
    }
   
SIGNAL(SIG_INTERRUPT0)//INT0,边沿触发中断
    {
    unsigned char temp,temp2=0;
    static unsigned char pre_TCNT2,j=0;
    if(INT0_time==0)//一个字节第一个下降沿中断,起始位开始
        {
        TCNT2=130;
        pre_TCNT2=130;
        RUDR="0xff";//接收的数据初值
        j="0";    //位数清零
        INT0_time++;//中断次数加一
        }
    else
        {
        temp="TCNT2";
        if(temp>pre_TCNT2)temp2=temp-pre_TCNT2;//取一个高/低电平的宽度
        if(temp2>10)//滤过窄电平(干扰信号)
            {
            pre_TCNT2=temp;//记录前一次的时间值
            temp="0";
            while(temp2>13)//计算位的个数,约13为一个位(8*13=104uS)
                    {
                    temp2-=13;//
                    temp++;
                    }
            if(temp2>6)temp++;//计算位的个数,一般13为一个位
            if(INT0_time==1)temp-=1;
            if(INT0_time&1)//奇数次中断
                {
                while(temp)//位0的个数
                    {
                    RUDR&=~(1<<j);//相关位置0
                    temp--;
                    j++;
                    }
                }
            else j+=temp;//偶数,位1的个数,跳过
            INT0_time++;//中断次数加一
            }
        }
    rtime="0";
    }

系统分类: 单片机
用户分类: 单片机
标签: 软件 模拟 串口 程序
来源: 原创
发表评论 阅读全文(144) | 回复(1)

2

关于投票
共享一个数码管计算小程序,很好用,绿色免安装

共享一个数码管计算小程序,很好用,绿色免安装

计算数码管代码的好工具,适用于各种单片机。

个人极力推荐,我就是用的这个,下载后要

下载区:

rar

系统分类: 单片机
用户分类: 单片机
标签: 共享 数码管计算 程序 绿色 免安装
来源: 原创
发表评论 阅读全文(99) | 回复(0)

3

关于投票
用I2C总线传输数据控制继电器工作---很使用哦

用I2C总线传输数据控制继电器工作---很使用哦

直接看程序吧,好的就哈~~~~~~~~~~~

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define dig_num P2
#define dig_seg P0
#define ADD_t1 0x10
#define ADD_t2 0x20
#define somenop();   _nop_();_nop_();_nop_();_nop_();_nop_();

bit ACK;             /*应答标志位*/
sbit jdq="P3"^7;
sbit key="P3"^3;
sbit led3=P1^2;
sbit led1=P1^0;
sbit sw1=P2^7;
sbit sw2=P2^6;
sbit sw3=P2^5;
sbit sw5=P2^3;
sbit sw6=P2^2;
sbit beep="P2"^0;
bit f_run,f_run_t;
sbit SDA="P3"^4;
sbit SCL="P3"^2;

uchar code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
uchar data count_1s;
uchar data buff_t1,buff_t2,t1,t2;
uchar data buff_led1,buff_led2,buff_led5,buff_led6,buff;
uchar dig_num0;
uchar data SLA _at_ 0x2e;
uchar data MTD _at_ 0x2f;
uchar data MRD _at_ 0x30;

void INT_0(void);
void delay(uint t);
void key_down(void);
void Input_I2C(uchar add,uchar add_t,uchar dat);
void Start_I2c();
void Stop_I2c();
void SendByte(uchar c);
void Ack_I2c(bit a);
uchar RcvByte(void);
//***********************************************************
void main(void)
{
 sw1=0;sw2=0;sw3=0;sw5=0;sw6=0;key=1;
 TMOD=0x01;
 TH0=0xf0;TL0=0x60;
 TCON=0x10;           //TR0=1,IE0=0;          
 IE=0x82;             //EA=1,EX0=1,ET0=1;

 Start_I2c();
 SLA=0xAE;
 SendByte(SLA);
 while(!ACK)SendByte(SLA);
 SendByte(ADD_t1);
 while(!ACK)SendByte(ADD_t1);
 Start_I2c();
 SLA=0xAF;
 SendByte(SLA);
 while(!ACK)SendByte(SLA);
 t1=RcvByte();
 Ack_I2c(ACK);
 Stop_I2c();
 buff_t1=t1;

 Start_I2c();
 SLA=0xAE;
 SendByte(SLA);
 while(!ACK)SendByte(SLA);
 SendByte(ADD_t2);
 while(!ACK)SendByte(ADD_t2);
 Start_I2c();
 SLA=0xAF;
 SendByte(SLA);
 while(!ACK)SendByte(SLA);
 t2=RcvByte();
 Ack_I2c(ACK);
 Stop_I2c();
 buff_t2=t2;
 
 while(1)
   {
    if(!key)key_down();            
    if(f_run_t==0){f_run=0;buff_t1=t1;buff_t2=t2;}
    }
 }
//***************************************************************
//***************************************************************
void key_down(void)
{
  if(sw1==0)     //加1
    {if(t1>=99){t1=0;
             beep="0";
    delay(30000);
    beep=1;}
        else{t1++;
             beep="0";
          delay(30000);
          beep="1";}
 buff_t1=t1;
 Input_I2C(0xae,ADD_t1,t1);
 delay(30000);
 }      
  else if(sw2==0)     //减1
         {if(t1==0){t1=99;
                 beep="0";
           delay(30000);
           beep="1";}
            else{t1--;
                 beep="0";
              delay(30000);
              beep="1";}
      buff_t1=t1;
      Input_I2C(0xae,ADD_t1,t1);
         }
        else if(sw3==0)
               {f_run=1;f_run_t=1;beep=0;delay(30000);beep=1;led1=0;}
 
             else if(sw5==0)
            {if(t2>=10){t2=0;         //加1
                              beep="0";
                        delay(30000);
                     beep="1";}
                          else{t2++;       //减1
                               beep="0";
                            delay(30000);
                            beep="1";}
                    buff_t2=t2;
                    Input_I2C(0xae,ADD_t2,t2);
                    }
                   else if(sw6==0)         
                          {if(t2==0){t2=10;
                                  beep="0";
                            delay(30000);
                            beep="1";}
                              else{t2--;
                                   beep="0";
                                delay(30000);
                                beep="1";}
                                   buff_t2=t2;
                         Input_I2C(0xae,ADD_t2,t2);
                         }
}   
//**************************************************************
void Input_I2C(uchar add,uchar add_t,uchar dat)
{
 Start_I2c();
 SLA=add;
 SendByte(SLA);
 while(!ACK)SendByte(SLA);
 SendByte(add_t);
 while(!ACK)SendByte(add_t);
 SendByte(dat);
 while(!ACK)SendByte(dat);
 Stop_I2c();
 }
/**********************************************************************************/
/**********************************************************************************/
 void INT_0(void)interrupt 1
 {TH0=0xf0;TL0=0x60;
  if(f_run){                          //有按键3按下,灯1亮,t1秒后,灯3亮?
            if(count_1s==250){count_1s=0;    //三秒后全部灭掉,数码管显示变化的时间
                              if(buff_t1==0){led3=0;jdq=1;
                                             if(buff_t2==0){led1=1;led3=1;jdq=0;f_run_t=0;}
                                             else buff_t2--;
                                             }
                              else buff_t1--;                                                                                       
                              }
                         else count_1s++;
            buff_led1=buff_t1/10;buff_led2=buff_t1%10;
            buff_led5=buff_t2/10;buff_led6=buff_t2%10;
            dig_num0=count_1s%4;
            switch(dig_num0)
              {case 0:dig_num=0x7f;
             dig_seg=table[buff_led1];
       break;