?? volume_16f876a_v30a_debug.c
字號:
#include <pic.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define PIC_CLK 20000000
#include "delay_alternative_enhanced_precision.h"
//__CONFIG(WDTDIS & XT & UNPROTECT & LVPDIS); // freq. clock 4MHz
//__CONFIG(WDTDIS & HS & UNPROTECT & LVPDIS); // freq. clock 20MHz
__CONFIG(WDTDIS & PWRTEN & HS & UNPROTECT & DEBUGDIS & BORDIS & LVPDIS);
#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))
static bit CSL @ PORTBIT(PORTA, 0);
static bit DAT @ PORTBIT(PORTA, 1);
static bit CLK @ PORTBIT(PORTA, 2);
static bit IR @ PORTBIT(PORTB, 0);
static bit WEN @ PORTBIT(PORTA, 3);
static bit VUP @ PORTBIT(PORTB, 1);
static bit VDW @ PORTBIT(PORTB, 2);
static bit ENC_A @ PORTBIT(PORTB, 4);
static bit ENC_B @ PORTBIT(PORTB, 5);
static bit LCD_RS @ PORTBIT(PORTA, 2);
static bit LCD_RW @ PORTBIT(PORTA, 4);
static bit LCD_EN @ PORTBIT(PORTA, 5);
//******************************************************************************
//* function declarationis & global variables
//******************************************************************************
void DelayMs(unsigned char);
void write_SPI(unsigned int, unsigned int);
void LCD_init(void);
void LCD_write_str(int, int, char *, int);
void LCD_write_data(unsigned char);
void LCD_write_cmd(unsigned char);
void LCD_wait_busy(void);
int byteToInt(unsigned char, unsigned char) ;
int intToByte(int, unsigned char *, unsigned char *);
void save_vol(int, int);
void set_volume(int, int);
void itoa(int, char *, int);
void uitoa(unsigned int, char*, int);
signed char rc5_receive(unsigned int *, unsigned int *) ;
signed char encoder(void);
void DelayBigUs(unsigned int cnt);
void DelayBigMs(unsigned int cnt) ;
unsigned char byte1, byte2, byte3, byte4;
char tmp[30];
unsigned int RC5addr = 0, RC5data = 0;
#define LOGO "AUDIODESIGNGUIDE"
#define VOLUME "Volume dB"
#define MAX_VOL (255)
#define MIN_VOL (0)
#define INC_VOL (2)
#define MAX_VDB (31)
#define MIN_VDB (-95)
#define INC_VDB (1)
void main()
{
int vol;
int vdb;
int volume_up = 0;
int volume_down = 0;
TRISA = 0b00000000; // All port A are output
TRISB = 0b11111111; // All port B are input
TRISC = 0b00000000; // All post C are output
ADCON1 = 0x06; // All posts AN4-7 to digital
PORTA = 0b00000000;
PORTC = 0b00000000;
DAT = 0;
CLK = 0;
WEN = 1;
CSL = 1;
//##################################################
//# starup interrupts
//##################################################
INTEDG = 0;
INTE = 1;
GIE = 1;
DelayMs(50);
//##################################################
//# display startup
//##################################################
LCD_init();
strcpy(tmp, LOGO);
LCD_write_str( 1, 1, tmp, 16);
//##################################################
//# get and set last saved volume level
//##################################################
byte1 = EEPROM_READ(0x00);
byte2 = EEPROM_READ(0x01);
byte3 = EEPROM_READ(0x02);
byte4 = EEPROM_READ(0x03);
vol = byteToInt(byte1, byte2);
vdb = byteToInt(byte3, byte4);
if (vol == -1 || vdb == -1)
{
vol = MIN_VOL;
vdb = MIN_VDB;
}
set_volume(vol, vdb);
//##################################################
//# main loop
//##################################################
while(1)
{
volume_up = volume_down = 0;
//##################################################
//# get data from infrared receiver
//##################################################
// 20: rc5 cd remote 10100
if (RC5addr == 20)
{
// 16: volume + 10000
// 17: volume - 10001
switch (RC5data)
{
case 16:
volume_up = 1;
break;
case 17:
volume_down = 1;
break;
}
RC5data = 0;
RC5addr = 0;
}
//##################################################
//# get input from button
//##################################################
if (VUP == 0) volume_up = 1;
if (VDW == 0) volume_down = 1;
//##################################################
//# get input from encder
//##################################################
#ifdef NO_ENCODER
switch(encoder())
{
case 1:
volume_up = 1;
break;
case -1:
volume_down = 1;
break;
}
#endif
//##################################################
//# elaborate input
//##################################################
if (volume_up)
{
if (vol < (MAX_VOL - INC_VOL))
{
vol += INC_VOL;
vdb += INC_VDB;
}
else
{
vol = MAX_VOL;
vdb = MAX_VDB;
}
set_volume(vol, vdb);
save_vol(vol, vdb);
volume_up = 0;
}
else if (volume_down)
{
if (vol > INC_VOL)
{
vol -= INC_VOL;
vdb -= INC_VDB;
}
else
{
vol = 0;
vdb = -95;
}
set_volume(vol, vdb);
save_vol(vol, vdb);
volume_down = 0;
}
}
}
//*********************************************************************
//* LCD read and write
//*********************************************************************
void LCD_init()
{
char * ptr, curr;
char LCDstr[] = { 0x3c, // 111100: 8bits, 2lines, 5x10dots
0x01, // clear display
0x0c, // 1100: display on, cursor off
0x06, // 110: auto-increment
0x00 };
ptr = LCDstr;
while(*ptr)
{
LCD_write_cmd(*ptr);
ptr++;
}
}
void LCD_wait_busy()
{
unsigned char busy;
int retry = 1000;
TRISC = 0xff;
LCD_RS = 0;
LCD_RW = 1; // read
asm("nop");
asm("nop");
do {
LCD_EN = 1;
asm("nop");
asm("nop");
busy = PORTC & 0x80;
LCD_EN = 0;
} while (busy && retry-- > 0);
TRISC = 0x00;
}
void LCD_write_cmd(unsigned char c)
{
LCD_wait_busy();
LCD_RW = 0;
LCD_RS = 0;
PORTC = c;
LCD_EN = 1;
LCD_EN = 0;
}
void LCD_write_data(unsigned char c)
{
LCD_wait_busy();
LCD_RW = 0;
LCD_RS = 1;
PORTC = c;
LCD_EN = 1;
LCD_EN = 0;
}
void LCD_write_str(int line, int pos, char * str, int len)
{
char * ptr;
unsigned char curr;
int i;
//*************************************************
// set the posistion and line
//*************************************************
if (line == 1)
curr = 0b10000000 + (pos - 1);
else
curr = 0b11000000 + (pos - 1);
LCD_write_cmd(curr);
//*************************************************
// send the string
//*************************************************
ptr = str;
for(i = 0; *ptr && i < len; i++)
{
LCD_write_data(*ptr);
ptr++;
}
}
void DelayMs(unsigned char cnt)
{
unsigned char i;
do {
i = 4;
do {
DelayUs(250);
} while(--i);
} while(--cnt);
}
void interrupt prv_int(void)
{
#define TIME_MIN (500)
#define TIME_MAX (1100)
#define TIME_STEP (200)
int OnTime, OffTime, i, k;
unsigned int data = 0, addr = 0;
if (INTF == 0) return;
INTF = 0;
for (OffTime = 0; !IR && OffTime < TIME_MAX; OffTime += TIME_STEP)
{
DelayUs(TIME_STEP);
tmp[0] = '0';
}
if (OffTime > TIME_MAX) return;
if (OffTime < TIME_MIN) return;
for (OnTime = 0; IR && OnTime < TIME_MAX; OnTime += TIME_STEP)
{
DelayUs(TIME_STEP);
tmp[1] = '1';
}
if (OnTime > TIME_MAX) return;
if (OnTime < TIME_MIN) return;
for (k = 0; k < 25; k++)
{
if (IR)
{
for (i = 0; IR && i <= OnTime; i += TIME_STEP)
{
DelayUs(TIME_STEP);
}
tmp[k+2] = '1';
}
else
{
for (i = 0; !IR && i <= OffTime; i += TIME_STEP)
{
DelayUs(TIME_STEP);
}
tmp[k+2] = '0';
}
}
tmp[k+2] = '\0';
addr = 0;
data = 0;
for (k = 0; k < 5; k++)
{
if (tmp[5 + (k * 2)] == '1')
{
addr <<= 1; addr |= 1;
}
else
{
addr <<= 1;
}
}
for (; k < 11; k++)
{
if (tmp[5 + (k * 2)] == '1')
{
data <<= 1; data |= 1;
}
else
{
data <<= 1;
}
}
RC5data = data;
RC5addr = addr;
return;
}
void set_volume(int vol, int vdb)
{
CSL = 0;
write_SPI(vol, 8);
write_SPI(vol, 8);
CSL = 1;
WEN = 0;
write_SPI(203, 8);
write_SPI(vol, 8);
WEN = 1;
strcpy(tmp, VOLUME);
LCD_write_str( 2, 1, tmp, 16);
//itoa(vol, tmp, 10);
//LCD_write_str( 2, 1, tmp);
itoa(vdb, tmp, 10);
LCD_write_str( 2, 8, tmp, 16);
}
void save_vol(int vol, int vdb)
{
intToByte(vol, &byte1, &byte2);
intToByte(vdb, &byte3, &byte4);
EEPROM_WRITE(0x00, byte1);
EEPROM_WRITE(0x01, byte2);
EEPROM_WRITE(0x02, byte3);
EEPROM_WRITE(0x03, byte4);
}
void write_SPI(unsigned int data, unsigned int n_bit)
{
unsigned int bit_mask;
int i;
bit_mask = 1 << (n_bit - 1);
for (i = 0; i < n_bit; i++)
{
CLK = 0;
if ((data & bit_mask) == 0)
DAT = 0;
else
DAT = 1;
CLK = 1;
data <<= 1;
}
}
//*********************************************************************
//* ENCODER - Checks rotary encoder and returns the following:
//*
//* 0: no movement
//* -1: ccw rotation
//* 1: cw rotation
//* from http://www.littlefishbicycles.com/preamp
//*********************************************************************
signed char encoder(void)
{
static unsigned char a, b;
if (!a & !b) {
if (ENC_A) {
a = ENC_A;
return (-1);
}
if (ENC_B) {
b = ENC_B;
return (1);
}
}
if (a & !b) {
if (!ENC_A) {
a = ENC_A;
return (1);
}
if (ENC_B) {
b = ENC_B;
return (-1);
}
}
if (a & b) {
if (!ENC_A) {
a = ENC_A;
return (-1);
}
if (!ENC_B) {
b = ENC_B;
return (1);
}
}
if (!a & b) {
if (ENC_A) {
a = ENC_A;
return (1);
}
if (!ENC_B) {
b = ENC_B;
return (-1);
}
}
return (0);
}
int intToByte(int integer, unsigned char * byte1, unsigned char * byte2)
{
*byte1 = (char)(integer >> 8);
*byte2 = (char)(integer);
return 0;
}
int byteToInt(unsigned char byte1, unsigned char byte2)
{
int integer;
integer = byte1;
integer <<= 8;
integer |= byte2;
return integer;
}
#define NUMBER_OF_DIGITS 14 /* space for NUMBER_OF_DIGITS + '\0' */
void uitoa(unsigned int value, char* string, int radix)
{
unsigned char index, i;
index = NUMBER_OF_DIGITS;
i = 0;
do {
string[--index] = '0' + (value % radix);
if ( string[index] > '9') string[index] += 'A' - ':'; /* continue with A, B,.. */
value /= radix;
} while (value != 0);
do {
string[i++] = string[index++];
} while ( index < NUMBER_OF_DIGITS );
string[i] = 0; /* string terminator */
}
void itoa(int value, char* string, int radix)
{
int val = value;
if (val < 10 && val > -10)
*string++ = ' ';
if (val < 0 && radix == 10)
{
*string++ = '-';
uitoa(-val, string, radix);
}
else
{
*string++ = ' ';
uitoa(val, string, radix);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -