搜档网
当前位置:搜档网 › 51单片机RC522射频卡驱动

51单片机RC522射频卡驱动

51单片机RC522射频卡驱动
51单片机RC522射频卡驱动

/*-----------------------------------------------.H文件-----------------------------------------*/

#ifndef __RC522_H_

#define __RC522_H_

/////////////////////////////////////////////////////////////////////

//MF522命令字

/////////////////////////////////////////////////////////////////////

#define PCD_IDLE 0x00 //取消当前命令

#define PCD_AUTHENT 0x0E //验证密钥

#define PCD_RECEIVE 0x08 //接收数据

#define PCD_TRANSMIT 0x04 //发送数据

#define PCD_TRANSCEIVE 0x0C //发送并接收数据

#define PCD_RESETPHASE 0x0F //复位

#define PCD_CALCCRC 0x03 //CRC计算

/////////////////////////////////////////////////////////////////////

//Mifare_One卡片命令字

/////////////////////////////////////////////////////////////////////

#define PICC_REQIDL 0x26 //寻天线区内未进入休眠状态#define PICC_REQALL 0x52 //寻天线区内全部卡

#define PICC_ANTICOLL1 0x93 //防冲撞

#define PICC_ANTICOLL2 0x95 //防冲撞

#define PICC_AUTHENT1A 0x60 //验证A密钥

#define PICC_AUTHENT1B 0x61 //验证B密钥

#define PICC_READ 0x30 //读块

#define PICC_WRITE 0xA0 //写块

#define PICC_DECREMENT 0xC0 //扣款

#define PICC_INCREMENT 0xC1 //充值

#define PICC_RESTORE 0xC2 //调块数据到缓冲区

#define PICC_TRANSFER 0xB0 //保存缓冲区中数据

#define PICC_HALT 0x50 //休眠

/////////////////////////////////////////////////////////////////////

//MF522 FIFO长度定义

/////////////////////////////////////////////////////////////////////

#define DEF_FIFO_LENGTH 64 //FIFO size=64byte

#define MAXRLEN 18

/////////////////////////////////////////////////////////////////////

//MF522寄存器定义

/////////////////////////////////////////////////////////////////////

// PAGE 0

#define RFU00 0x00

#define CommandReg 0x01

#define ComIEnReg 0x02 #define DivlEnReg 0x03 #define ComIrqReg 0x04 #define DivIrqReg 0x05 #define ErrorReg 0x06 #define Status1Reg 0x07 #define Status2Reg 0x08 #define FIFODataReg 0x09 #define FIFOLevelReg 0x0A #define WaterLevelReg 0x0B #define ControlReg 0x0C #define BitFramingReg 0x0D #define CollReg 0x0E #define RFU0F 0x0F // PAGE 1

#define RFU10 0x10 #define ModeReg 0x11 #define TxModeReg 0x12 #define RxModeReg 0x13 #define TxControlReg 0x14 #define TxAutoReg 0x15 #define TxSelReg 0x16 #define RxSelReg 0x17 #define RxThresholdReg 0x18 #define DemodReg 0x19 #define RFU1A 0x1A #define RFU1B 0x1B #define MifareReg 0x1C #define RFU1D 0x1D #define RFU1E 0x1E #define SerialSpeedReg 0x1F

// PAGE 2

#define RFU20 0x20 #define CRCResultRegM 0x21 #define CRCResultRegL 0x22 #define RFU23 0x23 #define ModWidthReg 0x24 #define RFU25 0x25 #define RFCfgReg 0x26 #define GsNReg 0x27 #define CWGsCfgReg 0x28 #define ModGsCfgReg 0x29 #define TModeReg 0x2A #define TPrescalerReg 0x2B

#define TReloadRegH 0x2C

#define TReloadRegL 0x2D

#define TCounterValueRegH 0x2E

#define TCounterValueRegL 0x2F

// PAGE 3

#define RFU30 0x30

#define TestSel1Reg 0x31

#define TestSel2Reg 0x32

#define TestPinEnReg 0x33

#define TestPinValueReg 0x34

#define TestBusReg 0x35

#define AutoTestReg 0x36

#define VersionReg 0x37

#define AnalogTestReg 0x38

#define TestDAC1Reg 0x39

#define TestDAC2Reg 0x3A

#define TestADCReg 0x3B

#define RFU3C 0x3C

#define RFU3D 0x3D

#define RFU3E 0x3E

#define RFU3F 0x3F

///////////////////////////////////////////////////////////////////// //和MF522通讯时返回的错误代码

///////////////////////////////////////////////////////////////////// #define MI_OK 0

#define MI_NOTAGERR (-1)

#define MI_ERR (-2)

#define SHAQU1 0X01

#define KUAI4 0X04

#define KUAI7 0X07

#define REGCARD 0xa1

#define CONSUME 0xa2

#define READCARD 0xa3

#define ADDMONEY 0xa4

//void delay_ns(uint16 ns);

void delay10us(void);

void delay1ms(void);

uint8 SPIReadByte(void);

void SPIWriteByte(uint8 SPIData);

char PcdRequest(uint8 req_code,uint8 *pTagType);

char PcdAnticoll(uint8 *pSnr);

char PcdSelect(unsigned char *pSnr);

char PcdAuthState(uint8 auth_mode,uint8 addr,uint8 *pKey,uint8 *pSnr);

char PcdRead(uint8 addr,uint8 *pData);

char PcdWrite(uint8 addr,uint8 *pData);

char PcdHalt(void);

void CalulateCRC(uint8 *pIndata,uint8 len,uint8 *pOutData);

char PcdReset(void);

char M500PcdConfigISOType(uint8 type);

uint8 ReadRawRC(uint8 Address);

void WriteRawRC(uint8 Address, uint8 value);

void SetBitMask(uint8 reg,uint8 mask);

void ClearBitMask(uint8 reg,uint8 mask);

char PcdComMF522(uint8 Command,uint8 *pInData,uint8 InLenByte,uint8 *pOutData,uint16 *pOutLenBit);

void PcdAntennaOn(void);

void PcdAntennaOff(void);

void InitRc522(void);

void delay1ms500us(void);

sbit SPI_CS = P1^3;

sbit SPI_CK = P1^4;

sbit SPI_MOSI = P1^5;

sbit SPI_MISO = P1^6;

sbit SPI_RST = P1^7;

#define SET_SPI_CS SPI_CS=1

#define CLR_SPI_CS SPI_CS=0

#define SET_SPI_CK SPI_CK=1

#define CLR_SPI_CK SPI_CK=0

#define SET_SPI_MOSI SPI_MOSI=1

#define CLR_SPI_MOSI SPI_MOSI=0

#define SET_SPI_MISO SPI_MISO

#define SET_RC522RST SPI_RST=1

#define CLR_RC522RST SPI_RST=0

#endif

/*-----------------------------------------------.c文件-----------------------------------------*/

#include "rc522.h"

/*void delay_ns(uint16 ns)

{

uint16 xdata i;

for(i=0;i

{

nop();

nop();

nop();

}

}*/

void delay10us(void) //误差0us

{

unsigned char a,b;

for(b=1;b>0;b--)

for(a=2;a>0;a--);

}

void delay1ms(void) //误差0us

{

unsigned char a,b,c;

for(c=1;c>0;c--)

for(b=142;b>0;b--)

for(a=2;a>0;a--);

}

void delay1ms500us(void) //误差0us

{

uint8 xdata a,b;

for(b=115;b>0;b--)

for(a=5;a>0;a--);

}

uint8 SPIReadByte(void)

{

uint8 xdata SPICount; // Counter used to clock out the data

uint8 xdata SPIData;

SPIData = 0;

for (SPICount = 0; SPICount < 8; SPICount++) // Prepare to clock in the data to be read

{

SPIData <<=1; // Rotate the data CLR_SPI_CK; nop();nop(); // Raise the clock to clock the data out of the MAX7456

if(SET_SPI_MISO)

{

SPIData|=0x01;

}

SET_SPI_CK; nop();nop(); // Drop the clock ready for the next bit

} // and loop back return (SPIData); // Finally return the read data

}

void SPIWriteByte(uint8 SPIData)

{

uint8 xdata SPICount; // Counter used to clock out the data

for (SPICount = 0; SPICount < 8; SPICount++)

{

if (SPIData & 0x80)

{

SET_SPI_MOSI;

}

else

{

CLR_SPI_MOSI;

} nop();nop();

CLR_SPI_CK;nop();nop();

SET_SPI_CK;nop();nop();

SPIData <<= 1;

}

}

/////////////////////////////////////////////////////////////////////

//功能:寻卡

//参数说明: req_code[IN]:寻卡方式

// 0x52 = 寻感应区内所有符合14443A标准的卡

// 0x26 = 寻未进入休眠状态的卡

// pTagType[OUT]:卡片类型代码

// 0x4400 = Mifare_UltraLight

// 0x0400 = Mifare_One(S50)

// 0x0200 = Mifare_One(S70)

// 0x0800 = Mifare_Pro(X)

// 0x4403 = Mifare_DESFire

//返回: 成功返回MI_OK

/////////////////////////////////////////////////////////////////////

char PcdRequest(uint8 req_code,uint8 *pTagType)

{

char xdata status;

uint16 xdata unLen;

uint8 xdata ucComMF522Buf[MAXRLEN];

ClearBitMask(Status2Reg,0x08);

WriteRawRC(BitFramingReg,0x07);

SetBitMask(TxControlReg,0x03);

ucComMF522Buf[0] = req_code;

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);

if ((status == MI_OK) && (unLen == 0x10))

{

*pTagType = ucComMF522Buf[0];

*(pTagType+1) = ucComMF522Buf[1];

}

else

{ status = MI_ERR; }

return status;

}

/////////////////////////////////////////////////////////////////////

//功能:防冲撞

//参数说明: pSnr[OUT]:卡片序列号,4字节

//返回: 成功返回MI_OK

/////////////////////////////////////////////////////////////////////

char PcdAnticoll(uint8 *pSnr)

{

char xdata status;

uint8 xdata i,snr_check=0;

uint16 xdata unLen;

uint8 xdata ucComMF522Buf[MAXRLEN];

ClearBitMask(Status2Reg,0x08);

WriteRawRC(BitFramingReg,0x00);

ClearBitMask(CollReg,0x80);

ucComMF522Buf[0] = PICC_ANTICOLL1;

ucComMF522Buf[1] = 0x20;

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);

if (status == MI_OK)

{

for (i=0; i<4; i++)

{

*(pSnr+i) = ucComMF522Buf[i];

snr_check ^= ucComMF522Buf[i];

}

if (snr_check != ucComMF522Buf[i])

{ status = MI_ERR; }

}

SetBitMask(CollReg,0x80);

return status;

}

/////////////////////////////////////////////////////////////////////

//功能:选定卡片

//参数说明: pSnr[IN]:卡片序列号,4字节

//返回: 成功返回MI_OK

/////////////////////////////////////////////////////////////////////

char PcdSelect(uint8 *pSnr)

{

char xdata status;

uint8 xdata i;

uint16 xdata unLen;

uint8 xdata ucComMF522Buf[MAXRLEN];

ucComMF522Buf[0] = PICC_ANTICOLL1;

ucComMF522Buf[1] = 0x70;

ucComMF522Buf[6] = 0;

for (i=0; i<4; i++)

{

ucComMF522Buf[i+2] = *(pSnr+i);

ucComMF522Buf[6] ^= *(pSnr+i);

}

CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);

ClearBitMask(Status2Reg,0x08);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);

if ((status == MI_OK) && (unLen == 0x18))

{ status = MI_OK; }

else

{ status = MI_ERR; }

return status;

}

/////////////////////////////////////////////////////////////////////

//功能:验证卡片密码

//参数说明: auth_mode[IN]: 密码验证模式

// 0x60 = 验证A密钥

// 0x61 = 验证B密钥

// addr[IN]:块地址

// pKey[IN]:密码

// pSnr[IN]:卡片序列号,4字节

//返回: 成功返回MI_OK

/////////////////////////////////////////////////////////////////////

char PcdAuthState(uint8 auth_mode,uint8 addr,uint8 *pKey,uint8 *pSnr)

{

char xdata status;

uint16 xdata unLen;

uint8 xdata i,ucComMF522Buf[MAXRLEN];

ucComMF522Buf[0] = auth_mode;

ucComMF522Buf[1] = addr;

for (i=0; i<6; i++)

{ ucComMF522Buf[i+2] = *(pKey+i); }

for (i=0; i<6; i++)

{ ucComMF522Buf[i+8] = *(pSnr+i); }

// memcpy(&ucComMF522Buf[2], pKey, 6);

// memcpy(&ucComMF522Buf[8], pSnr, 4);

status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);

if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))

{ status = MI_ERR; }

return status;

}

/////////////////////////////////////////////////////////////////////

//功能:读取M1卡一块数据

//参数说明: addr[IN]:块地址

// pData[OUT]:读出的数据,16字节

//返回: 成功返回MI_OK

/////////////////////////////////////////////////////////////////////

char PcdRead(uint8 addr,uint8 *pData)

{

char xdata status;

uint16 xdata unLen;

uint8 xdata i,ucComMF522Buf[MAXRLEN];

ucComMF522Buf[0] = PICC_READ;

ucComMF522Buf[1] = addr;

CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

if ((status == MI_OK) && (unLen == 0x90))

// { memcpy(pData, ucComMF522Buf, 16); }

{

for (i=0; i<16; i++)

{ *(pData+i) = ucComMF522Buf[i]; }

}

else

{ status = MI_ERR; }

return status;

}

/////////////////////////////////////////////////////////////////////

//功能:写数据到M1卡一块

//参数说明: addr[IN]:块地址

// pData[IN]:写入的数据,16字节

//返回: 成功返回MI_OK

/////////////////////////////////////////////////////////////////////

char PcdWrite(uint8 addr,uint8 *pData)

{

char xdata status;

uint16 xdata unLen;

uint8 xdata i,ucComMF522Buf[MAXRLEN];

ucComMF522Buf[0] = PICC_WRITE;

ucComMF522Buf[1] = addr;

CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))

{ status = MI_ERR; }

if (status == MI_OK)

{

//memcpy(ucComMF522Buf, pData, 16);

for (i=0; i<16; i++)

{

ucComMF522Buf[i] = *(pData+i);

}

CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);

if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))

{ status = MI_ERR; }

}

return status;

}

/////////////////////////////////////////////////////////////////////

//功能:命令卡片进入休眠状态

//返回: 成功返回MI_OK

/////////////////////////////////////////////////////////////////////

char PcdHalt(void)

{

char xdata status;

uint16 xdata unLen;

uint8 xdata ucComMF522Buf[MAXRLEN];

ucComMF522Buf[0] = PICC_HALT;

ucComMF522Buf[1] = 0;

CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

return MI_OK;

}

/////////////////////////////////////////////////////////////////////

//用MF522计算CRC16函数

/////////////////////////////////////////////////////////////////////

void CalulateCRC(uint8 *pIndata,uint8 len,uint8 *pOutData)

{

uint8 xdata i,n;

ClearBitMask(DivIrqReg,0x04);

WriteRawRC(CommandReg,PCD_IDLE);

SetBitMask(FIFOLevelReg,0x80);

for (i=0; i

{ WriteRawRC(FIFODataReg, *(pIndata+i)); }

WriteRawRC(CommandReg, PCD_CALCCRC);

i = 0xFF;

do

{

n = ReadRawRC(DivIrqReg);

i--;

}

while ((i!=0) && !(n&0x04));

pOutData[0] = ReadRawRC(CRCResultRegL);

pOutData[1] = ReadRawRC(CRCResultRegM);

}

/////////////////////////////////////////////////////////////////////

//功能:复位RC522

//返回: 成功返回MI_OK

/////////////////////////////////////////////////////////////////////

char PcdReset(void)

{

//PORTD|=(1<

SET_RC522RST;

delay10us();

//PORTD&=~(1<

CLR_RC522RST;

delay10us();

//PORTD|=(1<

SET_RC522RST;

delay10us();

WriteRawRC(CommandReg,PCD_RESETPHASE);

delay10us();

WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(TReloadRegL,30);

WriteRawRC(TReloadRegH,0);

WriteRawRC(TModeReg,0x8D);

WriteRawRC(TPrescalerReg,0x3E);

WriteRawRC(TxAutoReg,0x40);//必须要

return MI_OK;

}

//////////////////////////////////////////////////////////////////////

//设置RC632的工作方式

//////////////////////////////////////////////////////////////////////

char M500PcdConfigISOType(uint8 type)

{

if (type == 'A') //ISO14443_A

{

ClearBitMask(Status2Reg,0x08);

WriteRawRC(ModeReg,0x3D);//3F

WriteRawRC(RxSelReg,0x86);//84

WriteRawRC(RFCfgReg,0x7F); //4F

WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) WriteRawRC(TReloadRegH,0);

WriteRawRC(TModeReg,0x8D);

WriteRawRC(TPrescalerReg,0x3E);

delay1ms();

PcdAntennaOn();

}

else{ return -1; }

return MI_OK;

}

/////////////////////////////////////////////////////////////////////

//功能:读RC632寄存器

//参数说明:Address[IN]:寄存器地址

//返回:读出的值

/////////////////////////////////////////////////////////////////////

uint8 ReadRawRC(uint8 Address)

{

uint8 xdata ucAddr;

uint8 xdata ucResult=0;

CLR_SPI_CS;

ucAddr = ((Address<<1)&0x7E)|0x80;

SPIWriteByte(ucAddr);

ucResult=SPIReadByte();

SET_SPI_CS;

return ucResult;

}

///////////////////////////////////////////////////////////////////// //功能:写RC632寄存器

//参数说明:Address[IN]:寄存器地址

// value[IN]:写入的值

///////////////////////////////////////////////////////////////////// void WriteRawRC(uint8 Address, uint8 value)

{

uint8 xdata ucAddr;

CLR_SPI_CS;

ucAddr = ((Address<<1)&0x7E);

SPIWriteByte(ucAddr);

SPIWriteByte(value);

SET_SPI_CS;

}

///////////////////////////////////////////////////////////////////// //功能:置RC522寄存器位

//参数说明:reg[IN]:寄存器地址

// mask[IN]:置位值

///////////////////////////////////////////////////////////////////// void SetBitMask(uint8 reg,uint8 mask)

{

char xdata tmp = 0x0;

tmp = ReadRawRC(reg);

WriteRawRC(reg,tmp | mask); // set bit mask

}

///////////////////////////////////////////////////////////////////// //功能:清RC522寄存器位

//参数说明:reg[IN]:寄存器地址

// mask[IN]:清位值

///////////////////////////////////////////////////////////////////// void ClearBitMask(uint8 reg,uint8 mask)

{

char xdata tmp = 0x0;

tmp = ReadRawRC(reg);

WriteRawRC(reg, tmp & ~mask); // clear bit mask

}

///////////////////////////////////////////////////////////////////// //功能:通过RC522和ISO14443卡通讯

//参数说明:Command[IN]:RC522命令字

// pInData[IN]:通过RC522发送到卡片的数据

// InLenByte[IN]:发送数据的字节长度

// pOutData[OUT]:接收到的卡片返回数据

// *pOutLenBit[OUT]:返回数据的位长度

/////////////////////////////////////////////////////////////////////

char PcdComMF522(uint8 Command,uint8 *pInData,uint8 InLenByte,uint8 *pOutData,uint16 *pOutLenBit)

{

char xdata status = MI_ERR;

uint8 xdata irqEn = 0x00;

uint8 xdata waitFor = 0x00;

uint8 xdata lastBits;

uint8 xdata n;

uint16 xdata i;

switch (Command)

{

case PCD_AUTHENT:

irqEn = 0x12;

waitFor = 0x10;

break;

case PCD_TRANSCEIVE:

irqEn = 0x77;

waitFor = 0x30;

break;

default:

break;

}

WriteRawRC(ComIEnReg,irqEn|0x80);

ClearBitMask(ComIrqReg,0x80);

WriteRawRC(CommandReg,PCD_IDLE);

SetBitMask(FIFOLevelReg,0x80);

for (i=0; i

{ WriteRawRC(FIFODataReg, pInData[i]); }

WriteRawRC(CommandReg, Command);

if (Command == PCD_TRANSCEIVE)

{ SetBitMask(BitFramingReg,0x80); }

//i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms

i = 2000;

do

{

n = ReadRawRC(ComIrqReg);

i--;

}

while ((i!=0) && !(n&0x01) && !(n&waitFor));

ClearBitMask(BitFramingReg,0x80);

if (i!=0)

{

if(!(ReadRawRC(ErrorReg)&0x1B))

{

status = MI_OK;

if (n & irqEn & 0x01)

{ status = MI_NOTAGERR; }

if (Command == PCD_TRANSCEIVE)

{

n = ReadRawRC(FIFOLevelReg);

lastBits = ReadRawRC(ControlReg) & 0x07;

if (lastBits)

{ *pOutLenBit = (n-1)*8 + lastBits; }

else

{ *pOutLenBit = n*8; }

if (n == 0)

{ n = 1; }

if (n > MAXRLEN)

{ n = MAXRLEN; }

for (i=0; i

{ pOutData[i] = ReadRawRC(FIFODataReg); } }

}

else

{ status = MI_ERR; }

}

SetBitMask(ControlReg,0x80); // stop timer now

WriteRawRC(CommandReg,PCD_IDLE);

return status;

}

/////////////////////////////////////////////////////////////////////

//开启天线

//每次启动或关闭天险发射之间应至少有1ms的间隔

///////////////////////////////////////////////////////////////////// void PcdAntennaOn(void)

{

uint8 xdata i;

i = ReadRawRC(TxControlReg);

if (!(i & 0x03))

{

SetBitMask(TxControlReg, 0x03);

}

}

///////////////////////////////////////////////////////////////////// //关闭天线

///////////////////////////////////////////////////////////////////// void PcdAntennaOff(void)

{

ClearBitMask(TxControlReg, 0x03);

}

///////////////////////////////////////////////////////////////////// //rc522初始化

///////////////////////////////////////////////////////////////////// void InitRc522(void)

{

PcdReset();

PcdAntennaOff();

delay1ms500us();

PcdAntennaOn();

M500PcdConfigISOType( 'A' );

}

基于51单片机蜂鸣器发声的-C语言程序

说明:按下不同的按键会是SOUNDER发出不同频率的声音。本例使用延时函数实现不同频率的声音输出,以后也可使用定时器 */ #include #define uchar unsigned char #define uint unsigned int sbit BEEP=P3^7; sbit K1=P1^4; sbit K2=P1^5; sbit K3=P1^6; sbit K4=P1^7; //延时 void DelayMS(uint x) { uchar t; while(x--) for(t=0;t<120;t++); } //按周期t发音 void Play(uchar t) { uchar i; for(i=0;i<100;i++) { BEEP=~BEEP; DelayMS(t); } BEEP=0; } void main() { P1=0xff; BEEP=0; while(1) { if(K1==0) Play(1); if(K2==0) Play(2); if(K3==0) Play(3); if(K4==0) Play(4); } }

说明:程序运行时播放生日快乐歌,未使用定时器中断,所有频率完全用延时实现 */ #include #define uchar unsigned char #define uint unsigned int sbit BEEP=P3^7; //生日快乐歌的音符频率表,不同频率由不同的延时来决定 uchar code SONG_TONE[]= {212,212,190,212,159,169,212,212,190,212,142,159,212,212,106,126,159,169,190,1 19,119,126,159,142,159,0}; //生日快乐歌节拍表,节拍决定每个音符的演奏长短 uchar code SONG_LONG[]= {9,3,12,12,12,24,9,3,12,12,12,24, 9,3,12,12,12,12,12,9,3,12,12,12,24,0}; //延时 void DelayMS(uint x) { uchar t; while(x--) for(t=0;t<120;t++); } //播放函数 void PlayMusic() { uint i=0,j,k; while(SONG_LONG[i]!=0||SONG_TONE[i]!=0) { //播放各个音符,SONG_LONG为拍子长度 for(j=0;j

一个基于51单片机控制直流电机的设计

今天做的一个基于51单片机控制直流电机的设计 2010-09-12 18:47 可以实现的功能是: 按下左转键则开始向左转动 按下右转键则向右转动 按下停止键则开始逐渐停止转动 按下调速键一次则会加速一档 按下调速键二次则会加速二档 按下调速键三次则会加速三档 按下调速键四次则会加速四档 按下调速键五次则会回到最初速度重新记档位 设计思路: 直流电机只要能提供一定的直流就可以转动,改变电压极性可以改变转动方向,可以通过给直流电机提供脉冲信号来驱动它,脉冲信号的占空比可以影响到直流电机的平均速度,因此可以通过调整占空比从而能实现调速的目的。直流电机的驱动电路要有过流保护作用,图中的二极管就直到这个作用,另外电机的驱动电流是比较大的所以需要用三极管来放大电流。程序的关键就是如何实现占空比的调整,这个可以通过对51单片机定时器重装初值进行改变,从而改变时间。用51实现PWM信号的输出,相对麻烦点,要是AVR就可以方便地实现PWM 信号,由见51单片机的局限性与AVR单片机的优势。 原理图

详细程序: #include #define uchar unsigned char #define uint unsigned int sbit PW1=P2^0 ; sbit PW2=P2^1 ; //控制电机的两个输入 sbit accelerate=P2^2 ; //调速按键 sbit stop=P2^3 ; //停止按键 sbit left=P2^4 ; //左转按键 sbit right=P2^5 ; //右转按键 #define right_turn PW1=0;PW2=1 //顺时针转动 #define left_turn PW1=1;PW2=0 //逆向转动 #define end_turn PW1=1;PW2=1 //停转 uint t0=25000,t1=25000; //初始时占空比为50% uint a=25000; // 设置定时器装载初值 25ms 设定频率为20Hz uchar flag=1; //此标志用于选择不同的装载初值 uchar dflag; //左右转标志 uchar count; //用来标志速度档位 void keyscan(); //键盘扫描 void delay(uchar z); void time_init(); //定时器的初始化 void adjust_speed(); //通过调整占空比来调整速度 void main() {

51单片机控制的步进电机C语言程序

我上周刚做的这个实验成功拉,给你参考一下吧这可是我当时辛辛苦苦编出来的啊,不过我用的是L298驱动的和ULN2003一样,你把它换成2003就行拉 #include unsigned char code table[]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf 9,0x00,0xf1,0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0x00}; unsigned char temp,temp_old; unsigned char key; unsigned char i,j,k,m,s; void delay(int i) { for(m=i;m>0;m--) for(j=250;j>0;j--) for(k=10;k>0;k--); } void saomiao() { P3=0xff; P3_4=0; temp=P3; temp=temp&0x0f; if(temp!=0x0f) { for(i=50;i>0;i--)

for(j=200;j>0;j--); temp=P3; temp=temp&0x0f; if(temp!=0x0f) { temp=P3; temp=temp&0x0f; switch(temp) { case 0x0e: key=1; break; case 0x0d: key=2; break; case 0x0b: key=3; break; case 0x07: key=4; break; } temp=P3;

temp=temp&0x0f; while(temp!=0x0f) { temp=P3; temp=temp&0x0f; } } } P3=0xff; P3_5=0; temp=P3; temp=temp&0x0f; if(temp!=0x0f) { for(i=50;i>0;i--) for(j=200;j>0;j--); temp=P3; temp=temp&0x0f; if(temp!=0x0f) { temp=P3; temp=temp&0x0f; switch(temp)

51单片机控制直流电机PWM调速C语言程序

#include #define uchar unsigned char #define uint unsigned int sbit KEY1 = P3^4; sbit KEY2 = P3^5; sbit KEY3 = P3^6; sbit IN1 = P1^0; sbit IN2 = P1^1; sbit ENA = P1^2; sfr ldata=0x80; sbit dula=P2^6; sbit wela=P2^7; //sbit lcden=P3^4; //uchar timer,ms,t_set = 1; uchar T_N=100; uchar T_N1=100; uchar T_H_N=50; uchar T_H_N1=50; void msplay(uchar,uchar); uchar code x1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x27,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //uchar code x2[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; uchar code x3[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //uchar code x4[]={0x01,0x02,0x04,0x08,0x10,0x20}; void delay(uint z) //延时函数 { uint x; for(x=z;x>0;x--); }

基于51单片机的步进电机控制-设计报告(说明书)及源程序

南京XX大学 指导老师:张X 课程设计基于51单片机的步进电机控制 机械电子工程学院 测控技术与仪器 XXXXX Xxx 2012年1年4日

步进电机控制系统 [摘要]本课程设计的内容是利用51单片机,达到控制步进电机的启 动、停止、正转、反转、两档速度和状态显示的目的,使步进电机控制更加灵活。步进电机驱动芯片采用ULN2803,ULN2803具有大电流、高电压,外电路简单等优点。利用四位数码管增设电机状态显示功能,各项数据更直观。实测结果表明,该控制系统达到了设计的要求。 关键字:步进电机、数码管、51单片机、ULN2803 一步进电机与驱动电路 1.1 什么是步进电机 步进电机是一种将电脉冲转化为角位移的执行机构。通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时也可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。 1.2 步进电机的种类 步进电机分永磁式(PM)、反应式(VR)、和混合式(HB)三种。永磁式步进一般为两相,转矩和体积较小,步进角一般为7.5度或15度;反应式步进一般为三相,可实现大转矩输出,步进角一般为1.5度,但噪声和振动都很大。在欧美等发达国家80年代已被淘汰;混合式步进是指混合了永磁式和反应式的优点。它又分为两相和五相:两相步进角一般为1.8度而五相步进角一般为 0.72度。这种步进电机的应用最为广泛。 1.3 步进电机的特点 1.精度高一般的步进电机的精度为步进角的3-5%,且不累积。可在宽广的频率范围内通过改变脉冲频率来实现调速,快速起停、正反转控制及制动等,这是步进电动机最突出的优点 2.过载性好其转速不受负载大小的影响,不像普通电机,当负载加大时就会出现速度下降的情况,所以步进电机使用在对速度和位置都有严格要求的场合; 3.控制方便步进电机是以“步”为单位旋转的,数字特征比较明显,这样就给计算

蜂鸣器程序

单片机蜂鸣器实验 C程序: #include "reg51.h" #define uchar unsigned char #define uint unsigned int sbit FM=P2^3; void delay ( uchar x) { uint y; for (; x > 0 x-- ) for( y=500 y>0;y--); } void main() { FM=0; while(1) { delay(20); FM=1; delay(20); FM=0; } } 因为单片机的IO口驱动能力不够让蜂鸣器发出声音,所以我们通过三极管放大驱动电流,从而可以让蜂鸣器发出声音,你要是输出高电平,三极管导通,集电极电流通过蜂鸣器让蜂鸣器发出声音,当输出低电平时,三极管截止,没有电流流过蜂鸣器,所以就不会发出声音

单片机驱动蜂鸣器原理与设计 蜂鸣器是一种一体化结构的电子讯响器,本文介绍如何用单片机驱动蜂鸣器,他广泛应用于计算机、打印机、复印机、报警器、电话机等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场,振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。多谐振荡器由晶体管或集成电路构成,当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。下面是电磁式蜂鸣器的外形图片及结构图。。。电磁式蜂鸣器实物图:一、电磁式蜂鸣器驱动原理蜂鸣器发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发声的,因此需要一定的电流才能驱动它,单片机IO引脚输出的电流较小,单片机输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放大的电路。S51增强型单片机实验板通过一个三极管C8550来放大驱动蜂鸣器,原理图见下面图3:S51增强型单片机实验板蜂鸣器驱动原理图:如图所示,蜂鸣器的正极接到VCC(+5V)电源上面,蜂鸣器的负极接到三极管的发射极E,三极管的基级B经过限流电阻R1后由单片机的P3.7引脚控制,当P3.7输出高电平 时,三极管T1截止,没有电流流过线圈,蜂鸣器不发声;当P3.7输出低电平时,三极管导通,这样蜂鸣器的电流形成回路,发出声音。因此,我们可以通过程序控制P3.7脚的电平来使蜂鸣器发出声音和关闭。程序中改变单片机P3.7引脚输出波形的频率,就可以调整控制蜂鸣器音调,产生各种不同音色、音调的声音。另外,改变P3.7输出电平的高低电平占空比,则可以控制蜂鸣器的声音大小,这些我们都可以通过编程实验来验证。二、蜂鸣器列子下面我们举几个简单的单片机驱动蜂鸣器的编程和电路设计的列子。1、简单的蜂鸣器实验程序:本程序通过在P3.7输出一个音频范围的方波,驱动实验板上的蜂鸣器发出蜂鸣声,其中DELAY延时子程序的作用是使输出的方波频率在人耳朵听觉能力之内的20KHZ以下,如果没有这个延时程序的话,输出的频率将大大超出人耳朵的听觉能力,我们将不能听到声音。更改延时常数,可以改变输出频率,也就可以调整蜂鸣器的音调。大家可以在实验中更改#228为其他值,听听蜂鸣器音调的改变。 ORG 0000H AJMP MAIN ;跳转到主程序 ORG 0030H MAIN: CPL P3.7 ;蜂鸣器驱动电平取反 LCALL DELAY 延时 AJMP MAIN 反复循环 DELAY:MOV R7,#228 ;延时子程序,更改该延时常数可以改变蜂鸣器发出的音调 DE1: DJNZ R7,DE1 RET

基于51单片机控制直流电机的设计

可以实现的功能是: 按下左转键则开始向左转动 按下右转键则向右转动 按下停止键则开始逐渐停止转动 按下调速键一次则会加速一档 按下调速键二次则会加速二档 按下调速键三次则会加速三档 按下调速键四次则会加速四档 按下调速键五次则会回到最初速度重新记档位 设计思路: 直流电机只要能提供一定的直流就可以转动,改变电压极性可以改变转动方向,可以通过给直流电机提供脉冲信号来驱动它,脉冲信号的占空比可以影响到直流电机的平均速度,因此可以通过调整占空比从而能实现调速的目的。直流电机的驱动电路要有过流保护作用,图中的二极管就直到这个作用,另外电机的驱动电流是比较大的所以需要用三极管来放大电流。程序的关键就是如何实现占空比的调整,这个可以通过对51单片机定时器重装初值进行改变,从而改变时间。用51实现PWM信号的输出,相对麻烦点,要是AVR就可以方便地实现PWM信号,由见51单片机的局限性与AVR单片机的优势。 原理图

详细程序: #include #define uchar unsigned char #define uint unsigned int sbit PW1=P2^0 ; sbit PW2=P2^1 ; //控制电机的两个输入 sbit accelerate=P2^2 ; //调速按键 sbit stop=P2^3 ; //停止按键 sbit left=P2^4 ; //左转按键 sbit right=P2^5 ; //右转按键 #define right_turn PW1=0;PW2=1 //顺时针转动 #define left_turn PW1=1;PW2=0 //逆向转动 #define end_turn PW1=1;PW2=1 //停转 uint t0=25000,t1=25000; //初始时占空比为50% uint a=25000; // 设置定时器装载初值 25ms 设定频率为20Hz uchar flag=1; //此标志用于选择不同的装载初值 uchar dflag; //左右转标志 uchar count; //用来标志速度档位 void keyscan(); //键盘扫描 void delay(uchar z); void time_init(); //定时器的初始化 void adjust_speed(); //通过调整占空比来调整速度 void main()

基于51单片机控制步进电机

单片机原理及系统课程设计 1 引言 步进电机又称为脉冲电动机或阶跃电动机,它是基于最基本的电磁感应作用,将电脉冲信号转变为角位移或线位移的开环控制元件。单片机控制的步进电机广泛地应用于工业自动控制、数控机床、组合机床、机器人、计算机外围设备、照相机,大型望远镜,卫星天线定位系统等等。 随着经济的发展,技术的进步和电子技术的发展,步进电机的应用领域更加广阔,同时也对步进电机的运行性能提出了更高的要求。 步进电机的原始模型起源于1830年至1860年,1870年前后开始以控制为目的的尝试,应用于氩弧灯的电极输送机构中,这被认为最早的步进电机。 1950年后期晶体管的发明也逐渐应用在步进电机上,对于数字化的控制变得更为容易。到20世纪60年代后期,在步进电机本体方面随着永磁材料的发展,各种实用性步进电机应运而生。步进电机往后经过不断改良,使得今日步进电机已广泛运用在需要高定位精度、高分解能、高响应性、信赖性等灵活控制性高的机械系统中。 在生产过程中要求自动化、省人力、效率高的机器中,我们很容易发现步进电机的踪迹,尤其以重视速度、位置控制、需要精确操作各项指令动作的灵活控制性场合步进电机用得最多。

2 设计方案与原理 4.1 设计方案 设计一个51单片机四相步进电机控制系统要求系统具有如下功能: (1)由I/O口产生的时序方波作为电机控制信号; (2)信号经过驱动芯片驱动电机的运转; (3)电机的状态通过键盘控制,包括正转,反转,加速,减速,停止和单步运行。 4.2 设计原理 步进电机实际上是一个数字\角度转换器,也是一个串行的数\模转换器。步进电机的基本控制包括启停控制、转向控制、速度控制、换向控制4个方面。从结构上看,步进电机分为三相、四相、五相等类型,本次设计的是四相电机。四相步进电机的工作方式有单四拍、双四拍和单双八拍三种。 在本次设计中,我们使用的是四相单八拍的工作方式。通过P1口给A,B,C,D四相依次输出高电平即可实现步进电机的旋转,通过控制两次输出的间隔,即可实现对步进电机的速度控制。 图 2.1 步进电机内部结构截图 根据步进电机的相关相序表我们可以正常的控制电机的步进运行。

单片机控制蜂鸣器概要

单片机控制蜂鸣器20年月日

目录 绪论 (1) 1、硬件设计 (2) 1.1 总体设计图 (2) 1.2 简易结构框图 (2) 1.3各部分硬件设计及功能 (3) 1.3.1 蜂鸣器发声电路:(如图1.3.1) (3) 1.3.2 电源稳压电路: (4) 1.4 元件清单 (4) 2、软件设计 (5) 2.1设计思想 (5) 2.2 程序流程图 (5) 2.3 音调、节拍以及编码的确定方法 (6) 2.3.1音调的确定 (6) 2.3.2 节拍的确定 (8) 2.3.3 编码 (9) 3、电路仿真与分析 (10) 4、电路板焊接、调试 (11) 4.1 焊接 (11) 4.2 调试 (12) 5、讨论及进一步研究建议 (12) 6、心得 (12) 7、单片机音乐播放器程序实例(卡农) (13)

绪论 蜂鸣器播放音乐电路设计对于单片机初学者来说是一个简单易实现的课题。通过编写程序使单片机产生一定频率的方波信号,方波信号进入蜂鸣器便产生我们熟知的音调。 我们用定时/计数器使单片机产生方波,利用定时/计数器使输出管脚在一定周期内反复翻转,达到所需频率,而我们给定时/计数器的初始值就是我们的音符—半周期数据表,通过我们播放的音乐的乐谱,来对数据表进行调用。 我们用延时子程序来表示节拍,不同的节拍代表不同的延时。 完成此次设计之后完全可以进行扩展,例如增加按键以及LED灯光效果,制成一个简易的音乐盒,给人以视觉听觉等全方位的享受。

1、硬件设计1.1 总体设计图 1.2 简易结构框图

1.3各部分硬件设计及功能 1.3.1 蜂鸣器发声电路:(如图1.3.1) 图1.3.1 如图所示,蜂鸣器发声电路是播放音乐电路的主要执行电路,它由一个蜂鸣器,一个三极管和一个电位器组成。蜂鸣器负责发声,三极管将电流放大,而电位器则控制流过蜂鸣器电流的大小,来达到控制音量的目的。

基于89C51单片机直流电机控制及其程序

课程设计说明书 院系:船舶工程学院 班级: 姓名: 学号:

机电综合课程设计 设计题目:直流电机控制系统 立体目的:通过本次课程设计,达到培养学生综合应用所学知识,分析和解决实际工程问题,锻炼创造能力的目的。 技术要求:设计直流电机控制系统,包括:机械装配图,控制原理图和接线图,并编制相应的控制程序。 完成基于89C51单片机开发板的直流电机速度控制,启停 及正反转控制。 一.机械系统 由直流电机驱动滚珠丝杠实现滑台的平移。将电机的旋转运动通过滚珠丝杠转换为平台的直线运动。 系统组成:直流电机,底板,支座,光杠,滚珠丝杠,平台等。

二.电气系统 1. 直流电机 电机采用无刷直流电机,型号为:BL-2203C。其特点是调速范围宽,低速力矩大,运行平稳,低噪声,高效率。 电机接线,两股线,一股为电机线,一股为电机霍尔线。 2.驱动器 驱动器采用无刷直流电机驱动器。接线端子说明:

驱动器由220V交流供电。 驱动器调速方式 (1)内部电位器调速:逆时针旋转驱动器控制面板上的电位器,电机速度减小,顺时针则转速增大:由于测速需 要响应时间,速度显示会滞后。 (2)外部输入调速:将外接电位器的两端分别接于驱动器的“+12”和“COM”端上,将调解段接于“AVI”上 即可使用外接电位器调速,也可以通过其他控制单元 输入模拟电平信号到“AVI”端实现调速。 (3)多段速度选择:通过控制驱动器上的CH1—3三个端子的状态可以选择内部预先设定的几种转速。 电机运行/停止控制(R/S) 通过控制端子“R/S”相对于“COM”的通、断可以控制电机的运行和停止。端子“R/S”内部以电阻上 拉到+12,可以配合无源触点开关使用,也可以配合集电极开路的PLC 等控制单元;当“R/S”与端子“COM”断开时电机运行,反之电机停止。使用运行/停止端控制电机停止时,电机为自然停车,其运动规律与负载惯性有关;

基于AT89C51单片机的步进电动机控制系统设计

重庆科技大学 本科毕业论文 基于AT89C51单片机的步进电动机控制系统 设计 考生姓名: XXXXX X 准考证号: XXXXXXXXXXXX 专业层次:本科院(系):XXXXXXXXXXXXXXXXXXX 指导教师: XXXXXX 职称:讲师 重庆科技大学 二O一二年月日

基于AT89C51单片机的步进电动机控制系统 设计 考生姓名: XXXXXX 准考证号: XXXXXXXXXXXX 专业层次:本科 指导教师: XXXXXXX 院(系):机械与动力工程学院 重庆科技大学 二O一二年九月二十日

摘要 随着微电子和计算机技术的发展,步进电机的需求量与日俱增,它广泛用于打印机、电动玩具等消费类产品以及数控机床、工业机器人、医疗器械等机电产品中,其在各个国民经济领域都有应用。研究步进电机的控制系统,对提高控制精度和响应速度、节约能源等都具有重要意义。 步进电机是一种能将电脉冲信号转换成角位移或线位移的机电元件,步进电机控制系统主要由步进控制器,功率放大器及步进电机等组成。采用单片机控制,用软件代替上述步进控制器,使得线路简单,成本低,可靠性大大增加。软件编程可灵活产生不同类型步进电机励磁序列来控制各种步进电机的运行方式。 本设计是采用AT89C51单片机对步进电机的控制,通过I/O口输出的时序方波作为步进电机的控制信号,信号经过芯片ULN2003驱动步进电机。 实践证明,基于单片机控制的步进电机比传统的步进控制器具有更好的性能,更加简单、方便、可靠。本设计的主要研究对象就是开环伺服系统中最常用的执行器件——步进电机。 关键词:步进电机,单片机,正反转控制,键盘控制,LCD液晶显示

单片机控制蜂鸣器唱歌的原理

单片机控制蜂鸣器唱歌 的原理 Document serial number【UU89WT-UU98YT-UU8CB-UUUT-UUT108】

一般说来,单片机演奏音乐基本都是单音频率,它不包含相应幅度的谐波频率,也就是说不能象电子琴那样能奏出多种音色的声音。因此单片机奏乐只需弄清楚两个概念即可,也就是“音调”和“节拍”。音调表示一个音符唱多高的频率,节拍表示一个音符唱多长的时间。1)音调的确定 音调就是我们常说的音高。它是由频率来确定的!我们可以查出各个音符所对应的相 应的频率,那么现在就需要我们来用51来发出相应频率的声音! 我们常采用的方法就是通过单片机的定时器定时中断,将单片机上对应蜂鸣器的I/O口来回取反,或者说来回清零,置位,从而让蜂鸣器发出声音,为了让单片机发出不同频率的声音,我们只需将定时器予置不同的定时值就可实现。那么怎样确定一个频率所对应的定时器的定时值呢? 以标准音高A 为例: A 的频率f = 440 Hz, 其对应的周期为:T = 1/ f = 1/440 =2272μs 那么,单片机上对应蜂鸣器的I/O 口来回取反的时间应为: t = T/2 = 2272/2 = 1136 μs ,也就是清零、置位在一个周期内完成. 这个时间t 也就是单片机上定时器应有的中断触发时间。一般情况下,单片机奏乐时,其定时器为工作方式1,它以振荡器的十二分频信号为计数脉冲。设振荡器频率为f0 ,则定时器的予置初值由下式来确定: t = 12 * (TALL – THL)/ f0 式中TALL = 216= 65536,T HL为定时器待确定的计数初值。因此定时器的高低计数器的初值为: TH =THL/ 256 = ( TALL – t* f0/12) / 256

单片机课程设计完整版pwm直流电动机调速控制系统》

单片机原理及应用课程设计报告设计题目: 学院: 专业: 班级: 学号: 学生姓名: 指导教师: 年月日 目录

设计题目:PWM直流电机调速系统 本文设计的PWM直流电机调速系统,主要由51单片机、电源、H桥驱动电路、LED 液晶显示器、霍尔测速电路以及独立按键组成的电子产品。电源采用78系列芯片实现+5V、+15V对电机的调速采用PWM波方式,PWM是脉冲宽度调制,通过51单片机改变占空比实现。通过独立按键实现对电机的启停、调速、转向的人工控制,LED实现对测量数据(速度)的显示。电机转速利用霍尔传感器检测输出方波,通过51单片机对1秒内的方波脉冲个数进行计数,计算出电机的速度,实现了直流电机的反馈控制。 关键词:直流电机调速;定时中断;电动机;波形;LED显示器;51单片机 1 设计要求及主要技术指标: 基于MCS-51系列单片机AT89C52,设计一个单片机控制的直流电动机PWM调速控制装置。 设计要求 (1)在系统中扩展直流电动机控制驱动电路L298,驱动直流测速电动机。 (2)使用定时器产生可控的PWM波,通过按键改变PWM占空比,控制直流电动机的转速。 (3)设计一个4个按键的键盘。 K1:“启动/停止”。 K2:“正转/反转”。 K3:“加速”。 K4:“减速”。 (4)手动控制。在键盘上设置两个按键----直流电动机加速和直流电动机减速键。在手动状态下,每按一次键,电动机的转速按照约定的速率改变。 (5)*测量并在LED显示器上显示电动机转速(rpm).

(6)实现数字PID调速功能。 主要技术指标 (1)参考L298说明书,在系统中扩展直流电动机控制驱动电路。 (2)使用定时器产生可控PWM波,定时时间建议为250us。 (3)编写键盘控制程序,实现转向控制,并通过调整PWM波占空比,实现调速; (4)参考Protuse仿真效果图:图(1) 图(1) 2 设计过程 本文设计的直流PWM调速系统采用的是调压调速。系统主电路采用大功率GTR为开关器件、H桥单极式电路为功率放大电路的结构。PWM调制部分是在单片机开发平台之上,运用汇编语言编程控制。由定时器来产生宽度可调的矩形波。通过调节波形的宽度来控制H电路中的GTR通断时间,以达到调节电机速度的目的。增加了系统的灵活性和精确性,使整个PWM脉冲的产生过程得到了大大的简化。 本设计以控制驱动电路L298为核心,L298是SGS公司的产品,内部包含4通道逻辑驱动电路。是一种二相和四相电机的专用驱动器,即内含二个H桥的高电压大电流双全桥式驱动器,接收标准TTL逻辑电平信号,可驱动46V、2A以下的电机。可驱动2个电机,OUTl、OUT2和OUT3、OUT4之间分别接2个电动机。5、7、10、12脚接输入控制电平,控制电机的正反转,ENA,ENB接控制使能端,控制电机的停转。 本设计以AT89C52单片机为核心,如下图(2),AT89C52是一个低电压,高性能 8位,片内含8k bytes的可反复擦写的只读程序存储器和256 bytes的随机存取数据存储器(),器件采用的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。 图(2) 对直流电机转速的控制即可采用开环控制,也可采用闭环控制。与开环控制相比,速度控制闭环系统的机械特性有以下优越性:闭环系统的机械特性与开环系统机械特性相比,其性能大大提高;理想空载转速相同时,闭环系统的静差(额定负载时电机转速降落与理想空载转速之比)要小得多;当要求的静差率相同时, 闭环调速系统的调速范围可以大大提高。直流电机的速度控制方案如图(3)所示。

基于51系列单片机控制步进电机调速实验 (自动保存的)

基于51系列单片机控制步进电机调速实验 实验指导书 仇国庆编写 重庆邮电大学自动化学院 自动化专业实验中心 2009年2月

基于51系列单片机控制步进电机调速实验 实验目的及要求: 1、熟悉步进电机的工作原理 2、熟悉51系列单片机的工作原理及调试方法 3、设计基于51系列单片机控制的步进电机调速原理图(要求实现电机的速度反馈测量,测量方式:数字测量) 4、实现51系列单片机对步进电机的速度控制(步进电机由实验中心提供,具体型号42BYG )由按钮控制步进电机的启动与停止;实现加速、匀速、和减速控制。速度设定由键盘设定,步进电机的反馈速度由LED 数码管显示。 实验原理: 步进电机控制原理 一般电动机都是连续旋转,而步进电动却是一步一步转动的,故叫步进电动机。步进电机是数字控制电机,它将脉冲信号转变成角位移,即给一个脉冲信号,步进电机就转动一个角度,因此非常适合于单片机控制。步进电机可分为反应式步进电机(简称VR)、永磁式步进电机(简称PM)和混合式步进电机(简称HB)。因此步进电动机是一种把脉冲变为角度位移(或直线位移)的执行元件。步进电动机的转子为多极分布,定子上嵌有多相星形连接的控制绕组,由专门电源输入电脉冲信号,每输入一个脉冲信号,步进电动机的转子就前进一步。由于输入的是脉冲信号,输出的角位移是断续的,所 以又称为脉冲电动机。随着数字控制系统的发展,步进电动机的应用将 逐渐扩大。 步进电机区别于其他控制电机的最大特点是,它是通过输入脉冲信号来 进行控制的,即电机的总转动角度由输入脉冲数决定,而电机的转速由 脉冲信号频率决定。步进电机的驱动电路根据控制信号工作,控制信号 可以由单片机产生。 电机转子均匀分布着很多小齿,定子齿有三个励磁绕阻,其几 何轴线依次分别与转子齿轴线错开。0、1/3て、2/3て,(相邻 两转子齿轴线间的距离为齿距以て表示),即A与齿1相对齐, B与齿2向右错开1/3て,C与齿3向右错开2/3て,A'与齿5相对齐,(A'就是A,齿5就是齿1)下面是定转子的展开图:(图2所示)

单片机驱动蜂鸣器原理与程序学习资料

单片机驱动蜂鸣器原 理与程序

单片机驱动蜂鸣器原理与设计 作者:mcu110 来源:51hei 点击数:12159 更新时间:2007年08月01日【字体:大中小】 蜂鸣器是一种一体化结构的电子讯响器,本文介绍如何用单片机驱动蜂鸣器,他广泛应用于计算机、打印机、复印机、报警器、电话机等电子产品中作发声器件。 蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场,振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。多谐振荡器由晶体管或集成电路构成,当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。 下面是电磁式蜂鸣器的外形图片及结构图。。。 电磁式蜂鸣器实物图:电磁式蜂鸣器结构示意图:

图 1 图 2 电磁式蜂鸣器内部构成: 1. 防水贴纸 2. 线轴 3. 线圈 4. 磁铁 5. 底座 6. 引脚 7. 外壳 8. 铁芯 9. 封胶 10. 小铁片 11. 振动膜 12. 电路板 一、电磁式蜂鸣器驱动原理 蜂鸣器发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发声的,因此需要一定的电流才能驱动它,单片机IO引脚输出的电流较小,单片机输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放大的电路。S51增强型单片机实验板通过一个三极管C8550来放大驱动蜂鸣器,原理图见下面图3: S51增强型单片机实验板蜂鸣器驱动原理图:

基于51单片机的直流电机调速的方法

基于51单片机的直流电机调速的方法 田云史洁黑龙江农业经济职业学院机电工程系157041 0 引言 许多单片机爱好者,在设计一些单片机控制系统的时候,都会采用小型直流电动机来制作各种各样的电子设备,因为直流电机调速范围广,易于平滑调速,启动、制动和过载转矩大,易于控制,可靠性较高。对于直流电机的控制,无非是控制其转向,以及速度。转向的控制方法比较简单,只要改变电机的通电极性就可改变其旋转方向。在这里,我们重点讨论如何对其速度上的控制,对其调速可以采用多种办法。对于直流电机转速的调节,最常用的办法是通过改变电枢端的电压来实现,传统的思路是通过调节电枢电路电阻R的阻值来改变端电压,以达到调速的目的。但由于接入的电阻消耗了部分电压,因此这种传统的调速方法效率很低。随着电力电子技术的发展,出现了许多新的电枢电压控制方法,其中PWM(Pulse Width Modulation)控制是常用的一种调速方法。PWM控制是指在保持周期丁不变的情况下,通过调节开关导通的时间对脉冲宽度进行调制,从而达到调节电机转速的目的。在脉宽调速系统中,电机电枢两端的电压是脉宽可调的脉冲电压,在输出脉冲频率足够快的情况下,由于惯性的存在,只要按照一定的规律改变通、断电的时间,即可使电机的速度达到并保持一个稳定值。对于直流电机,采用PWM控制技术构成的无级调速系统,启停时对直流系统无冲击,并且具有启动功耗小、运行稳定的特点。本文在给出直流电机调速和PWM实现方法的基础上,提供一种用51单片机软件实现PWM调速的方法。 1 PWM基本原理 PWM是通过控制固定电压的直流电源开关频率,从而改变负载两端的电压,进而达到控制要求的一种电压调整方法。PWM可以应用在许多方面,如电机调速、温度控制、压力控制等。在PWM驱动控制的调整系统中,按一个固定的频率来接通和断开电源,并根据需要改变一个周期内“接通”和“断开”时间的长短。通过改变直流电机电枢上电压的“占空比”来改变平均电压的大小,从而控制电动机的转速。因此,PWM又被称为“开关驱动装置”。如图1所示,在脉冲作用下,当电机通电时,速度增加;电机断电时,速度逐渐减少。只要按一定规律,改变通、断电的时间,即可让电机转速得到控制。

基于单片机的直流电机调速系统的课程设计

一、总体设计概述 本设计基于8051单片机为主控芯片,霍尔元件为测速元件, L298N为直流伺服电机的驱动芯片,利用 PWM调速方式控制直流电机转动的速度,同时可通过矩 阵键盘控制电机的启动、加速、减速、反转、制动等操作,并由LCD显示速度的变化值。 二、直流电机调速原理 根据直流电动机根据励磁方式不同,分为自励和它励两种类型,其机械特性曲线有所不同。但是对于直流电动机的转速,总满足下式: 式中U——电压; Ra——励磁绕组本身的内阻; ——每极磁通(wb ); Ce——电势常数; Ct——转矩常数。 由上式可知,直流电机的速度控制既可以采用电枢控制法也可以采用磁场控制法。磁场控制法控制磁通,其控制功率虽然较小,但是低速时受到磁场和磁极饱和的限制,高速时受到换向火花和换向器结构强度的限制,而且由于励磁线圈电感较大,动态响应较差,所以在工业生产过程中常用的方法是电枢控制法。 电枢控制法在励磁电压不变的情况下,把控制电压信号加到电机的电枢上来控制电机的转速。传统的改变电压方法是在电枢回路中串连一个电阻,通过调节电阻改变电枢电压,达到调速的目的,这种方法效率低,平滑度差,由于串联电阻上要消耗电功率,因而经济效益低,而且转速越慢,能耗越大。随着电力电子的发展,出现了许多新的电枢电压控制法。如:由交流电源供电,使用晶闸管整流器进行相控调压;脉宽调制(PWM)调压等。调压调速法具有平滑度高、能耗低、精度高等优点,在工业生产中广泛使用,其中PWM应用更广泛。脉宽调速利用一个固定的频率来控制电源的接通或断开,并通过改变一个周期内“接通”和“断开”时间的长短,即改变直流电机电枢上的电压的“占空比”来改变平均电. 压的大小,从而控制电动机的转速,因此,PWM又被称为“开关驱动装置”。如 果电机始终接通电源是,电机转速最大为Vmax,占空比为D=t1/t,则电机的平均转速:Vd=Vmax*D,可见只要改变占空比D,就可以调整电机的速度。平均转 速Vd与占空比的函数曲线近似为直线。 三、系统硬件设计

基于单片机的直流电机转速测量与显示-精品

目录 绪论 (2) 第1章参数计算与设备选型 (3) 1.1控制芯片 (3) 1.2测速发电机 (4) 1.3模数转化器件——ADC0809 (6) 第2章系统设计 (9) 2.1 系统方框图 (9) 2.2 硬件设计 (10) 2.2.1 直流测速发电机 (10) 2.2.2 ADC0809与单片机连接 (10) 2.2.3 数码管 (11) 2.2.4 综合接线图 (11) 2.3 软件设计 (12) 2.3.1 程序设计思路说明 (12) 2.3.2 总程序控制流程图 (13) 2.3.3 ADC0809工作流程图及程序 (14) 2.3.4显示部分工作流程图及程序 (15) 第3章结论 (18) 参考文献 (19)

绪论 在现代工业自动化高度发展的时期,几乎所有的工业设备都离不开电机,形形色色的电机在不同领域发挥着很重要的作用。与之而来的问题是,如何更好地控制电机,对于不同的场合,对电机的控制要求是不同的,但大部分都会涉及到直流电机的转速测量,从而利用转速来实施对直流电机的控制。 直流电机转速作为直流电机的一项重要技术指标,在各个应用场合都有重要的研究价值,例如在发动机,电动机,机床主轴等旋转设备的试验运转和控制中,常需要分时或连续测量,显示其转速及瞬时速度等,转速是其他大部分技术参数的计算来源,因此,准确测量直流电动机的转速具有重要的研究意义和理论价值。 目前,对直流电动机的速度检测方法很多,从整体上可分为模拟检测和数字检测方法。 模拟检测:即利用测速电机作为发电机,通过检测反电势E的大小和极性可得到转速N和电机转向,采用这种方法直接可以得到转速N和输出电压的特性曲线,直观,但也有很多不足,比如在高速和低速情况下实际输出偏离理想特性。 数字检测技术:即通过分析数字信号产生的一系列脉冲间接获取电机转速。如光电旋转编码器是将检测圆盘划分为等距的三个同心圆,最外环和次外环分别用等距的黑白条纹分开,且最外环和次外环的缝隙位置相位差为90度,用于判断电机的转速,最内环只有一个黑条纹,用作定位脉冲或者是复位脉冲,利用光电编码器输出的脉冲可以计算转速,具体的又可分为M法,T法和M\T法。 此外,市场上已经有了技术成熟的电机测速装置,如利用霍尔元件设计制作的直流电机测速仪等,凭借其精度高,稳定性好等优势占有重要的一席之地。 而本次微机控制原理课程设计的任务是直流电机速度的测量与显示。主要要求是通过测速直流发电机作为传感器,检测直流电机的转速,并输出与转速相关的电压,通过ADC0809芯片将测速发电机输出电压转换成电压的数字信号。控制芯片采用AT89C51将采集转换后的数字信号进行处理,得到转速,并通过四位数码管予以显示。整体上能够完成从转速检测到数据处理到显示的一整套功能。

51单片机控制四相步进电机解析

51单片机控制四相步进电机 2009年07月21日星期二 12:44 51单片机控制四相步进电机 2009-03-01 18:53 接触单片机快两年了,不过只是非常业余的兴趣,实践却不多,到现在还算是个初学者吧。这几天给自己的任务就是搞定步进电机的单片机控制。以前曾看过有关步进电机原理和控制的资料,毕竟自己没有做过,对其具体原理还不是很清楚。今天从淘宝网买了一个EPSON的UMX-1型步进电机,此步进电机为双极性四相,接线共有六根,外形如下 图所示: 详细内容: https://www.sodocs.net/doc/2f17525879.html,/31907887_d.h tml

拿到步进电机,根据以前看书对四相步进电机的了解,我对它进行了初步的测试,就是将5伏电源的正端接上最边上两根褐色的线,然后用5伏电源的地线分别和另外四根线(红、兰、白、橙)依次接触,发现每接触一下,步进电机便转动一个角度,来回五次,电机刚好转一圈,说明此步进电机的步进角度为360/(4×5)=18度。地线与四线接触的顺序相反,电机的转向也相反。 如果用单片机来控制此步进电机,则只需分别依次给四线一定时间的脉冲电流,电机便可连续转动起来。通过改变脉冲电流的时间间隔,就可以实现对转速的控制;通过改变给四

线脉冲电流的顺序,则可实现对转向的控制。所以,设计了如下电路图: C51程序代码为: 代码一 #include static unsigned int count; static unsigned int endcount; void delay(); void main(void)

相关主题