最新日志

发表于:2008-7-5 10:57:43
标签:无标签

0

LM317应用

点击开大图

点击开大图点击开大图

 

点击此处查看原文 >>

系统分类: 电源技术   |    用户分类: 无分类    |    来源: 无分类

评论(0) | 阅读(69)
发表于:2008-7-5 10:23:55
标签:无标签

0

M8--LCD1602程序


LCD ----PortD
LCD_RS ---PortC.0
LCD_RW --PortC.1
LCD_E ---PortC.2

 

//#include <avr/io.h>
//#include <avr/delay.h>

#define LCD_RS 0
#define LCD_RW 1
#define LCD_E 2

// LCD_putchar writes a character to the LCD at the current address, no busy flag check is done before or after
//the character is written!
//usage: LCD_putchar('A'); or LCD_putchar(0x55);
void LCD_putchar(char data)
{
//PortD is output
DDRD = 0xFF;
//put data on bus
PORTD = data;
//RW low, E low
PORTC &= ~((1<<LCD_RW)|(1<<LCD_E));
//RS high, strobe E
PORTC |= ((1<<LCD_RS)|(1<<LCD_E));
//the number of nops required varies with your clock frequency, try it out!
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
//RS low again, E low (belongs to strobe)
PORTC &= ~((1<<LCD_RS)|(1<<LCD_E));
//release bus
DDRD = 0;
}

//LCD_getaddress reads the address counter and busy flag. For the address only, mask off bit7 of the return
//value.
char LCD_getaddr(void)
{
//make var for the return value
char address;
//PortD is input
DDRD = 0;
//RW high, strobe enable
PORTC |= ((1<<LCD_RW)|(1<<LCD_E));
asm volatile ("nop");
asm volatile ("nop");
//while E is high, get data from LCD
address = PIND;
//reset RW to low, E low (for strobe)
PORTC &= ~((1<<LCD_RW)|(1<<LCD_E));
//return address and busy flag
return address;
}

//LCD_wait reads the address counter (which contains the busy flag) and loops until the busy flag is cleared.
void LCD_wait(void)
{
//get address and busy flag
//and loop until busy flag cleared
while((LCD_getaddr() & 0x80) == 0x80)
}

//LCD_command works EXACTLY like LCD_putchar, but takes RS low for accessing the command reg
//see LCD_putchar for details on the code
void LCD_command(char command)
{
DDRD = 0xFF;
PORTD = command;
PORTC &= ~((1<<LCD_RS)|(1<<LCD_RW)|(1<<LCD_E));
PORTC |= (1<<LCD_E);
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
PORTC &= ~(1<<LCD_E);
DDRD = 0;
}

/*LCD_init initialises the LCD with the following paramters:
8 bit mode, 5*7 font, 2 lines (also for 4 lines)
auto-inc cursor after write and read
cursor and didsplay on, cursor blinking.
*/
void LCD_init(void)
{
//setup the LCD control signals on PortC
DDRC |= ((1<<LCD_RS)|(1<<LCD_RW)|(1<<LCD_E));
PORTC = 0x00;
//if called right after power-up, we'll have to wait a bit (fine-tune for faster execution)
_delay_loop_2(0xFFFF);
//tell the LCD that it's used in 8-bit mode 3 times, each with a delay inbetween.
LCD_command(0x30);
_delay_loop_2(0xFFFF);
LCD_command(0x30);
_delay_loop_2(0xFFFF);
LCD_command(0x30);
_delay_loop_2(0xFFFF);
//now: 8 bit interface, 5*7 font, 2 lines.
LCD_command(0x38);
//wait until command finished
LCD_wait();
//display on, cursor on (blinking)
LCD_command(0x0F);
LCD_wait();
//now clear the display, cursor home
LCD_command(0x01);
LCD_wait();
//cursor auto-inc
LCD_command(0x06);
}

//now it's time for a simple function for showing strings on the LCD. It uses the low-level functions above.
//usage example: LCD_write("Hello World!");
void LCD_write(char* dstring)
{
//is the character pointed at by dstring a zero? If not, write character to LCD
while(*dstring)
{
//if the LCD is bus, let it finish the current operation
LCD_wait();
//the write the character from dstring to the LCD, then post-inc the dstring is pointing at.
LCD_putchar(*dstring++);
}
}

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 整理

评论(0) | 阅读(26)
发表于:2008-7-5 10:02:53
标签:无标签

0

M8--ADC转换一例

.org 0x0000
rjmp reset
 
.org 0x000E
rjmp ADC_ISR
 
reset:
ldi r16, low(RAMEND)
out SPL, r16
ldi r16, high(RAMEND)
out SPH, r16
 
ldi r16, 0xFF
out DDRD, r16
 
ldi r16, 0
out ADMUX, r16
ldi r16, 0b11101101
out ADCSR, r16
 
sei
 
loop:
rjmp loop
 
ADC_ISR:
push r16
in r16, SREG
push r16
push r17
 
in r16, ADCL
in r17, ADCH
lsr r17
ror r16
lsr r17
ror r16

com r16
out PortD, r16

pop r17
pop r16
out SREG, r16
pop r16
reti



; ADC转换中断向量
; 堆设定

;
;
;
;
;
;
; 设置PortD输出
;
;
;  写零
; 选择ADC0通道
; 从左到右: ADC使能,启动转换,自由振荡的方式,
;
;
; 开中断
;循环
;
;
;
; Here it is, our ISR!
; save r16
; use r16 16 to save SREG
; (push both on stack)
; also save r17
;
; 先取得最后ADC结果,低字节,
;
; shift ADC result right (2 bits)
; 转移它入r17
;
;两次
;
; PortD写;
;
;恢复
;
;

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 整理

评论(0) | 阅读(22)
发表于:2008-7-5 9:53:53
标签:无标签

0

M8---24C16读写程序

#include <avr\io.h>
#include <avr\delay.h>
#include <inttypes.h>
#include "lcd.h"

/*******************************************************************************
* TWI_init: sets bitrate in TWBR and prescaler in TWSR
* TWI_action: writes command to TWCR and takes care of TWINT and TWEN setting
* waits for TWI action to be completed and returns status code
* TWI_start: generates start condition and returns status code
* TWI_stop: generate stop condition and returns status code
* TWI_write_data: writes data to TWI bus and returns status code
* TWI_read_data: reads data from bus to TWDR and returns status code.
* if put_ack > 0, an ACK will be sent after the data has been received.
* TWI_wait: waits for a given slave address to be ACKed. Only use if slave has
* ACKed its address before. Loops forever if slave not present!
* EE_read_data: reads one data byte from a given address
* returns different error codes (zero if success) and data in TWDR
* EE_write_data: write one data byte to a given address
* returns different error codes (zero if success)
*******************************************************************************/
void TWI_init(char bitrate, char prescaler);
char TWI_action(char command);
char TWI_start(void);
void TWI_stop(void);
char TWI_write_data(char data);
char TWI_read_data(char put_ack);
void TWI_wait(char slave);
char EE_write_byte(const int address, const char data);
char EE_read_byte(const int address);

#define EE_ADDR 0xA0

/******************************************************************************/
void main (void)
{
//init LCD
LCD_init();
//set TWBR = 32 for 100kHz SCL @ 8MHz
TWI_init(32, 0);

//write 0x55 @ 513 and print return value on LCD
LCD_puthex(EE_write_byte(513, 0x55));
//send stop
TWI_stop();
LCD_wait();
LCD_putchar(' ');
//wait for the EEPROM to finish the write operation
TWI_wait(EE_ADDR);
//read the write location again and print return code on LCD
LCD_puthex(EE_read_byte(513));
LCD_wait();
LCD_putchar(' ');
//print the value read from the EEPROM on the LCD
LCD_puthex(TWDR);
TWI_stop();
//LCD should now show "0x00 0x00 0x55_"
//where the _ is the blinking cursor.
}

/******************************************************************************/
void TWI_init(char bitrate, char prescaler)
//sets bitrate and prescaler
{
TWBR = bitrate;
//mask off the high prescaler bits (we only need the lower three bits)
TWSR = prescaler & 0x03;
}

/******************************************************************************/
char TWI_action(char command)
//starts any TWI operation (not stop), waits for completion and returns the status code
//TWINT and TWEN are set by this function, so for a simple data transfer just use TWI_action(0);
{ //make sure command is good
TWCR = (command|(1<<TWINT)|(1<<TWEN));
//wait for TWINT to be set after operation has been completed
while(!(TWCR & (1<<TWINT)));
//return status code with prescaler bits masked to zero
return (TWSR & 0xF8);
}

/******************************************************************************/
char TWI_start(void)
//uses TWI_action to generate a start condition, returns status code
{ //TWI_action writes the following command to TWCR: (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
return TWI_action(1<<TWSTA);
//return values should be 0x08 (start) or 0x10 (repeated start)
}

/******************************************************************************/
void TWI_stop(void)
//generates stop condition
{ //as TWINT is not set after a stop condition, we can't use TWI_action here!
TWCR = ((1<<TWINT)|(1<<TWSTO)|(1<<TWEN));
//status code returned is 0xF8 (no specific operation)
}

/******************************************************************************/
char TWI_write_data(char data)
//loads data into TWDR and transfers it. Works for slave addresses and normal data
//waits for completion and returns the status code.
{ //just write data to TWDR and transmit it
TWDR = data;
//we don't need any special bits in TWCR, just TWINT and TWEN. These are set by TWI_action.
return TWI_action(0);
//status code returned should be:
//0x18 (slave ACKed address)
//0x20 (no ACK after address)
//0x28 (data ACKed by slave)
//0x30 (no ACK after data transfer)
//0x38 (lost arbitration)
}

/******************************************************************************/
char TWI_read_data(char put_ack)
{ //if an ACK is to returned to the transmitting device, set the TWEA bit
if(put_ack)
return(TWI_action(1<<TWEA));
//if no ACK (a NACK) has to be returned, just receive the data
else
return(TWI_action(0));
//status codes returned:
//0x38 (lost arbitration)
//0x40 (slave ACKed address)
//0x48 (no ACK after slave address)
//0x50 (AVR ACKed data)
//0x58 (no ACK after data transfer)
}

/******************************************************************************/
void TWI_wait(char slave)
{
//send slave address until a slave ACKs it. Good for checking if the EEPROM
//has finished a write operation. Use carefully! If the wrong slave address
//is being waited for, this function will end in an infinite loop.
do {
TWI_start();
} while(TWI_write_data(slave) != 0x18);
TWI_stop();
}

/******************************************************************************/
char EE_write_byte(const int address, const char data)
{
char dummy;
//we need this for the first if()
dummy = TWI_start();
//if the start was successful, continue, otherwise return 1
if((dummy != 0x08) && (dummy != 0x10))
return TWSR;
//now send the EEPROM slave address together with the address bits 8..10 for page select
//address format:
//|bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0 |
//| EE_ADDR   |  page select | R/W |
if(TWI_write_data(EE_ADDR|((address>>7) & 0x000E)) != 0x18)
return TWSR;
//now send the word address byte
if(TWI_write_data((char)(address)) != 0x28)
return TWSR;
//now send the data byte
if(TWI_write_data(data) != 0x28)
return TWSR;
//if everything was OK, return zero.
return 0;
}

/******************************************************************************/
char EE_read_byte(const int address)
{
char dummy;
//we need this for the first if()
dummy = TWI_start();
//as in EE_write_byte, first send the page address and the word address
if((dummy != 0x08) && (dummy != 0x10))
return TWSR;
if(TWI_write_data(EE_ADDR|((address>>7) & 0x000E)) != 0x18)
return TWSR;
if(TWI_write_data((char)(address)) != 0x28)
return TWSR;
//send a repeated start for entering master receiver mode
if(TWI_start() != 0x10)
return TWSR;
//send slave address, now with the read bit set
if(TWI_write_data((EE_ADDR|1)|((address>>7) & 0x000E)) != 0x40)
return TWSR;
//now get the data from the EEPROM, don't return ACK
if(TWI_read_data(0) != 0x58)
return TWSR;
//if everything was OK, return zero
return 0;
}

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 整理

评论(0) | 阅读(39)
发表于:2008-7-5 9:44:39
标签:无标签

0

M8--LCD1602四线控制程序

;*******************************************************************************
;	File:	m8_LCD_4bit.asm
;      Title:	ATmega8 driver for LCD in 4-bit mode (HD44780)
;  Assembler:	AVR assembler/AVR Studio
;    Version:	1.0
;    Created:	April 5th, 2004
;     Target:	ATmega8
; Christoph Redecker, http://www.avrbeginners.net
;*******************************************************************************

; Some notes on the hardware:
;ATmega8 (clock frequency doesn't matter, tested with 1 MHz to 8 MHz)
; PortD.1 -> LCD RS (register select)
; PortD.2 -> LCD RW (read/write)
; PortD.3 -> LCd E (Enable)
; PortD.4 ... PortD.7 -> LCD data.4 ... data.7
; the other LCd data lines can be left open or tied to ground.

.include "c:\program files\atmel\avr studio\appnotes\m8def.inc"

.equ	LCD_RS	= 1
.equ	LCD_RW	= 2
.equ	LCD_E	= 3

.def	temp	= r16
.def	argument= r17		;argument for calling subroutines
.def	return	= r18		;return value from subroutines

.org 0
rjmp reset

reset:
	ldi	temp, low(RAMEND)
	out	SPL, temp
	ldi	temp, high(RAMEND)
	out	SPH, temp

;LCD after power-up: ("*" means black bar)
;|****************|
;|		  |

	rcall	LCD_init
	
;LCD now:
;|&		  | (&: cursor, blinking)
;|		  |
	
	rcall	LCD_wait
	ldi	argument, 'A'	;write 'A' to the LCD char data RAM
	rcall	LCD_putchar
	
;|A&		  |
;|		  |
	
	rcall	LCD_wait
	ldi	argument, 0x80	;now let the cursor go to line 0, col 0 (address 0)
	rcall	LCD_command	;for setting a cursor address, bit 7 of the commands has to be set
	
;|A		  | (cursor and A are at the same position!)
;|		  |
	
	rcall	LCD_wait
	rcall	LCD_getchar	;now read from address 0
	
;|A&		  | (cursor is also incremented after read operations!!!)
;|		  |
	
	push	return		;save the return value (the character we just read!)
	
	rcall	LCD_delay
	pop	argument	;restore the character
	rcall	LCD_putchar	;and print it again

;|AA&		  | (A has been read from position 0 and has then been written to the next pos.)
;|		  |
		
loop:	rjmp loop	

lcd_command8:	;used for init (we need some 8-bit commands to switch to 4-bit mode!)
	in	temp, DDRD		;we need to set the high nibble of DDRD while leaving
					;the other bits untouched. Using temp for that.
	sbr	temp, 0b11110000	;set high nibble in temp
	out	DDRD, temp		;write value to DDRD again
	in	temp, PortD		;then get the port value
	cbr	temp, 0b11110000	;and clear the data bits
	cbr	argument, 0b00001111	;then clear the low nibble of the argument
					;so that no control line bits are overwritten
	or	temp, argument		;then set the data bits (from the argument) in the
					;Port value
	out	PortD, temp		;and write the port value.
	sbi	PortD, LCD_E		;now strobe E
	nop
	nop
	nop
	cbi	PortD, LCD_E
	in	temp, DDRD		;get DDRD to make the data lines input again
	cbr	temp, 0b11110000	;clear data line direction bits
	out	DDRD, temp		;and write to DDRD
ret

lcd_putchar:
	push	argument		;save the argmuent (it's destroyed in between)
	in	temp, DDRD		;get data direction bits
	sbr	temp, 0b11110000	;set the data lines to output
	out	DDRD, temp		;write value to DDRD
	in	temp, PortD		;then get the data from PortD
	cbr	temp, 0b11111110	;clear ALL LCD lines (data and control!)
	cbr	argument, 0b00001111	;we have to write the high nibble of our argument first
					;so mask off the low nibble
	or	temp, argument		;now set the argument bits in the Port value
	out	PortD, temp		;and write the port value
	sbi	PortD, LCD_RS		;now take RS high for LCD char data register access
	sbi	PortD, LCD_E		;strobe Enable
	nop
	nop
	nop
	cbi	PortD, LCD_E
	pop	argument		;restore the argument, we need the low nibble now...
	cbr	temp, 0b11110000	;clear the data bits of our port value
	swap	argument		;we want to write the LOW nibble of the argument to
					;the LCD data lines, which are the HIGH port nibble!
	cbr	argument, 0b00001111	;clear unused bits in argument
	or	temp, argument		;and set the required argument bits in the port value
	out	PortD, temp		;write data to port
	sbi	PortD, LCD_RS		;again, set RS
	sbi	PortD, LCD_E		;strobe Enable
	nop
	nop
	nop
	cbi	PortD, LCD_E
	cbi	PortD, LCD_RS
	in	temp, DDRD
	cbr	temp, 0b11110000	;data lines are input again
	out	DDRD, temp
ret

lcd_command:	;same as LCD_putchar, but with RS low!
	push	argument
	in	temp, DDRD
	sbr	temp, 0b11110000
	out	DDRD, temp
	in	temp, PortD
	cbr	temp, 0b11111110
	cbr	argument, 0b00001111
	or	temp, argument

	out	PortD, temp
	sbi	PortD, LCD_E
	nop
	nop
	nop
	cbi	PortD, LCD_E
	pop	argument
	cbr	temp, 0b11110000
	swap	argument
	cbr	argument, 0b00001111
	or	temp, argument
	out	PortD, temp
	sbi	PortD, LCD_E
	nop
	nop
	nop
	cbi	PortD, LCD_E
	in	temp, DDRD
	cbr	temp, 0b11110000
	out	DDRD, temp
ret

LCD_getchar:
	in	temp, DDRD		;make sure the data lines are inputs
	andi	temp, 0b00001111	;so clear their DDR bits
	out	DDRD, temp
	sbi	PortD, LCD_RS		;we want to access the char data register, so RS high
	sbi	PortD, LCD_RW		;we also want to read from the LCD -> RW high
	sbi	PortD, LCD_E		;while E is high
	nop
	in	temp, PinD		;we need to fetch the HIGH nibble
	andi	temp, 0b11110000	;mask off the control line data
	mov	return, temp		;and copy the HIGH nibble to return
	cbi	PortD, LCD_E		;now take E low again
	nop				;wait a bit before strobing E again
	nop	
	sbi	PortD, LCD_E		;same as above, now we're reading the low nibble
	nop
	in	temp, PinD		;get the data
	andi	temp, 0b11110000	;and again mask off the control line bits
	swap	temp			;temp HIGH nibble contains data LOW nibble! so swap
	or	return, temp		;and combine with previously read high nibble
	cbi	PortD, LCD_E		;take all control lines low again
	cbi	PortD, LCD_RS
	cbi	PortD, LCD_RW
ret					;the character read from the LCD is now in return

LCD_getaddr:	;works just like LCD_getchar, but with RS low, return.7 is the busy flag
	in	temp, DDRD
	andi	temp, 0b00001111
	out	DDRD, temp
	cbi	PortD, LCD_RS
	sbi	PortD, LCD_RW
	sbi	PortD, LCD_E
	nop
	in	temp, PinD
	andi	temp, 0b11110000
	mov	return, temp
	cbi	PortD, LCD_E
	nop
	nop
	sbi	PortD, LCD_E
	nop
	in	temp, PinD
	andi	temp, 0b11110000
	swap	temp
	or	return, temp
	cbi	PortD, LCD_E
	cbi	PortD, LCD_RW
ret

LCD_wait:				;read address and busy flag until busy flag cleared
	rcall	LCD_getaddr
	andi	return, 0x80
	brne	LCD_wait
	ret


LCD_delay:
	clr	r2
	LCD_delay_outer:
	clr	r3
		LCD_delay_inner:
		dec	r3
		brne	LCD_delay_inner
	dec	r2
	brne	LCD_delay_outer
ret

LCD_init:
	
	ldi	temp, 0b00001110	;control lines are output, rest is input
	out	DDRD, temp
	
	rcall	LCD_delay		;first, we'll tell the LCD that we want to use it
	ldi	argument, 0x20		;in 4-bit mode.
	rcall	LCD_command8		;LCD is still in 8-BIT MODE while writing this command!!!

	rcall	LCD_wait
	ldi	argument, 0x28		;NOW: 2 lines, 5*7 font, 4-BIT MODE!
	rcall	LCD_command		;
	
	rcall	LCD_wait
	ldi	argument, 0x0F		;now proceed as usual: Display on, cursor on, blinking
	rcall	LCD_command
	
	rcall	LCD_wait
	ldi	argument, 0x01		;clear display, cursor -> home
	rcall	LCD_command
	
	rcall	LCD_wait
	ldi	argument, 0x06		;auto-inc cursor
	rcall	LCD_command
ret

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 整理

评论(0) | 阅读(25)
发表于:2007-10-23 17:36:09
评论(1) | 阅读(563)
发表于:2007-10-21 19:38:05
评论(2) | 阅读(649)
发表于:2007-10-21 19:31:18
评论(1) | 阅读(804)
发表于:2007-10-5 16:46:09
标签:232  

0

232电路图二则

一。

点击看大图

二。

点击看大图

点击看大图

 

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 整理

评论(0) | 阅读(497)
发表于:2007-10-2 15:25:43
标签:7107  

0

评论(0) | 阅读(749)
总共 , 当前 /,23下一页