Binary numbers
// The following macros build values in binary. Nybbles are separated by
// commas for readability. If a non-binary digit is used, a compiler error
// will result. Here are some examples of the usage of the binary macros:
//
// B4 (0110) = 0x06
// B8 (0101,0101) = 0x55
// B16 (1010,1010, 0101,0101) = 0xAA55
// B32 (1000,0000, 1111,1111, 1010,1010, 0101,0101) = 0x80FFAA55
//
// For maximum readability, the bytes should be separated by spaces and there
// should be no spaces between nybbles, as shown above. Note that an enum
// isn't used because MISRA-C generates errors otherwise.
#define b0000 0u
#define b0001 1u
#define b0010 2u
#define b0011 3u
#define b0100 4u
#define b0101 5u
#define b0110 6u
#define b0111 7u
#define b1000 8u
#define b1001 9u
#define b1010 10u
#define b1011 11u
#define b1100 12u
#define b1101 13u
#define b1110 14u
#define b1111 15u
#pragma diag_suppress = Pm120
#define B4(n0) (b##n0) //!< Build a nybble in binary
#pragma diag_default = Pm120
#define B8(n1, n0) ((B4 (n1) << 4u) | B4 (n0))
//!< Build a byte in binary
#define B16(n3, n2, n1, n0) \
((B4 (n3) << 12) | (B4 (n2) << 8) | (B4 (n1) << 4) | B4 (n0))
//!< Build a halfword in binary
#define B32(n7, n6, n5, n4, n3, n2, n1, n0) \
((B4 (n7) << 28) | (B4 (n6) << 24) | (B4 (n5) << 20) | (B4 (n5) << 16) \
| (B4 (n3) << 12) | (B4 (n2) << 8) | (B4 (n1) << 4) | B4 (n0))
//!< Build a word in binary
#define B64(nF, nE, nD, nC, nB, nA, n9, n8, n7, n6, n5, n4, n3, n2, n1, n0) \
((B4 (nF) << 60) | (B4 (nE) << 56) | (B4 (nD) << 52) | (B4 (nC) << 48) \
| (B4 (nB) << 44) | (B4 (nA) << 40) | (B4 (n9) << 36) | (B4 (n8) << 32) \
| (B4 (n7) << 28) | (B4 (n6) << 24) | (B4 (n5) << 20) | (B4 (n5) << 16) \
| (B4 (n3) << 12) | (B4 (n2) << 8) | (B4 (n1) << 4) | B4 (n0))
//!< Build a long in binaryStepper motor controller for precise movement
/*
* IBM-PC Parallel Printer Port Data & Status Registers
* ====================================================
* 7 6 5 4 3 2 1 0 I/O Port
* +---+---+---+---+---+---+---+---+ ========
* Data | C8| C7| C6| C5| C4| C3| C2| C1| Base = 278/378/3BC Hex
* +---+---+---+---+---+---+---+---+ +---+
*/
#include<sys/io.h>
#include<unistd.h>
#include<stdlib.h>
#include<math.h> //for floor()
#include<iostream>
using namespace std;
#define BASEPORT 0x378 //SPP - Standard Parallel port base address
class stepper
{
private:
long delay; //delay betn each step
float pi; //constant
float acf, lcf; //angle and length correction factors in percentage
float r, c; // radius and circumerence of wheel
float ns;
int nfsc, nhs;
float residue;
// number of total steps, full step cycles and number of half steps
float step_rating; //number of steps per revolution
float speed; //speed of stepper in cm/sec
float l,w; //length and width of robocar
public:
stepper(float spd);
void specification();
void length2steps(float len, int& nfsc, int& nhs);//conversion
void angle2steps(float angle, int& nfsc, int& nhs);//conversion
void move(int nfsc, int nhs, int leftw, int rightw); //move
void fwd(float len); //length in cm
void bkwd(float len); //length in cm
void righturn(float degree, int degree_of_freedom); //number of degree turns
void lefturn(float degree, int degree_of_freedom); // -- do --
};
stepper:: stepper(float spd=7)
{
speed=spd;
l=18; //length of car
w=17-2; //width of car
acf=-2; //angle correction factor in percentage
lcf=-4; //angle correction factor in percentage
pi=3.14159; //costant
step_rating=200.5; //step rating
r=3.448; //radius of wheel in cm
c=2*pi*r; //circumference
residue=0;
//speed being in cm/s
delay=long(1/(step_rating/c*speed)*1000*1000); //in microsecond
}
void stepper::specification()
{
cout<<"\n\n\n\t\tF R O N T I E R\n";
cout<<"\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
cout<<"\n\n\nDesigned by: Amit Kumar Karna";
cout<<"\n\n\nMission: Vitrubio, Technozion'06 @ NIT Warangal";
cout<<"\n\n\nROBOCAR specifications...";
cout<<"\nDimensions = "<<l<<"cm x"<<w<<"cm";
cout<<"\nWheel Dia = "<<2*r<<"cm";
cout<<"\nStepper motor: 12V-0.33A \t"<<step_rating<<" steps/revolution";
cout<<"\nLength n Angle correction factors: "<<lcf<<"% & "<<acf<<"% respectively";
cout<<"\nSpeed selected : "<<speed<<"cm/sec";
cout<<"\ndelay between each step = "<<delay/1000.0<<"ms";
cout<<endl<<endl<<endl;
}
void stepper::length2steps(float len, int& nfsc, int& nhs)//conversion
{
ns=step_rating/c*len+residue;
nfsc=int(ns/4);
nhs=int(floor((ns-nfsc*4)/0.5)); //rounding
if(nhs==8) //may result after rounding
nhs=7;
residue=ns-(nfsc*4+nhs*0.5);
}
void stepper::angle2steps(float angle, int& nfsc, int& nhs)//conversion
{
float arclen=(pi*w)/360.0*angle;
length2steps(arclen, nfsc, nhs);
}
void stepper::move(int nfsc, int nhs, int leftw, int rightw) //move
{
int i;
int cnt;
outb(0x00, BASEPORT);
if(leftw==1 && rightw==1)
{
for(i=0; i<nfsc; i++)
{
outb(0x59, BASEPORT);
usleep(delay);
outb(0x6A, BASEPORT);
usleep(delay);
outb(0xA6, BASEPORT);
usleep(delay);
outb(0x95, BASEPORT);
usleep(delay);
if(i%50==0 && i!=0)
outb(0x81, BASEPORT); //one half step - as a compensation
}
//sequence after 5 i.e. 0100 is 1 for half step
//sequence after 9 i.e. 1001 is 8 for half step
for(i=0; i<1; i++) //dummy loop to use break;
{
cnt=0;
if(nhs==0)
break;
outb(0x81, BASEPORT);
if(++cnt==nhs)
break;
outb(0xA9, BASEPORT);
if(++cnt==nhs)
break;
outb(0x28, BASEPORT);
if(++cnt==nhs)
break;
outb(0x6A, BASEPORT);
if(++cnt==nhs)
break;
outb(0x42, BASEPORT);
if(++cnt==nhs)
break;
outb(0x56, BASEPORT);
if(++cnt==nhs)
break;
outb(0x14, BASEPORT);
if(++cnt==nhs)
break;
//max of 7 half steps only possible
}
}
else if(leftw==-1 && rightw==-1)
{
for(i=0; i<nfsc; i++)
{
outb(0x95, BASEPORT);
usleep(delay);
outb(0xA6, BASEPORT);
usleep(delay);
outb(0x6A, BASEPORT);
usleep(delay);
outb(0x59, BASEPORT);
usleep(delay);
if(i%50==0 && i!=0)
outb(0x81, BASEPORT); //one half step - as a compensation
}
//sequence after 5 i.e. 0100 is 1 for half step
//sequence after 9 i.e. 1001 is 8 for half step
for(i=0; i<1; i++) //dummy loop
{
cnt=0;
if(nhs==0)
break;
outb(0x81, BASEPORT);
if(++cnt==nhs)
break;
outb(0xA9, BASEPORT);
if(++cnt==nhs)
break;
outb(0x28, BASEPORT);
if(++cnt==nhs)
break;
outb(0x6A, BASEPORT);
if(++cnt==nhs)
break;
outb(0x42, BASEPORT);
if(++cnt==nhs)
break;
outb(0x56, BASEPORT);
if(++cnt==nhs)
break;
outb(0x14, BASEPORT);
if(++cnt==nhs)
break;
}
}
else if(leftw==-1 && rightw==1) //left turn 2 wheels
{
for(i=0;i<nfsc;i++)
{
outb(0x99, BASEPORT);
usleep(delay);
outb(0xAA, BASEPORT);
usleep(delay);
outb(0x66, BASEPORT);
usleep(delay);
outb(0x55, BASEPORT);
usleep(delay);
}
//sequence after 5 i.e. 0100 is 1 for half step
cnt=0;
for(i=0; i<1; i++)
{
if(nhs==0)
break;
outb(0x11, BASEPORT);
if(++cnt==nhs)
break;
outb(0x99, BASEPORT);
if(++cnt==nhs)
break;
outb(0x88, BASEPORT);
if(++cnt==nhs)
break;
outb(0xAA, BASEPORT);
if(++cnt==nhs)
break;
outb(0x22, BASEPORT);
if(++cnt==nhs)
break;
outb(0x66, BASEPORT);
if(++cnt==nhs)
break;
outb(0x44, BASEPORT);
if(++cnt==nhs)
break;
//max of 7 half steps only possible
}
}
else if(leftw==1 && rightw==-1) //right turn with 2 wheels
{
for(i=0;i<nfsc;i++)
{
outb(0x55, BASEPORT);
usleep(delay);
outb(0x66, BASEPORT);
usleep(delay);
outb(0xAA, BASEPORT);
usleep(delay);
outb(0x99, BASEPORT);
usleep(delay);
}
//sequence after 5 i.e. 0100 is 1 for half step
cnt=0;
for(i=0; i<1; i++)
{
if(nhs==0)
break;
outb(0x44, BASEPORT);
if(++cnt==nhs)
break;
outb(0x66, BASEPORT);
if(++cnt==nhs)
break;
outb(0x22, BASEPORT);
if(++cnt==nhs)
break;
outb(0xAA, BASEPORT);
if(++cnt==nhs)
break;
outb(0x88, BASEPORT);
if(++cnt==nhs)
break;
outb(0x99, BASEPORT);
if(++cnt==nhs)
break;
outb(0x11, BASEPORT);
if(++cnt==nhs)
break;
//max of 7 half steps only possible
}
}
else if(leftw==0 && rightw==1) //left turn with one wheel
{
for(i=0;i<nfsc;i++)
{
outb(0x09, BASEPORT);
usleep(delay);
outb(0x0A, BASEPORT);
usleep(delay);
outb(0x06, BASEPORT);
usleep(delay);
outb(0x05, BASEPORT);
usleep(delay);
}
//sequence after 5 i.e. 0100 is 1 for half step
cnt=0;
for(i=0; i<1; i++)
{
if(nhs==0)
break;
outb(0x01, BASEPORT);
if(++cnt==nhs)
break;
outb(0x09, BASEPORT);
if(++cnt==nhs)
break;
outb(0x08, BASEPORT);
if(++cnt==nhs)
break;
outb(0x0A, BASEPORT);
if(++cnt==nhs)
break;
outb(0x02, BASEPORT);
if(++cnt==nhs)
break;
outb(0x06, BASEPORT);
if(++cnt==nhs)
break;
outb(0x04, BASEPORT);
if(++cnt==nhs)
break;
//max of 7 half steps only possible
}
}
else if(leftw==1 && rightw==0) //right turn with one wheel
{
for(i=0;i<nfsc;i++)
{
outb(0x50, BASEPORT);
usleep(delay);
outb(0x60, BASEPORT);
usleep(delay);
outb(0xA0, BASEPORT);
usleep(delay);
outb(0x90, BASEPORT);
usleep(delay);
}
//sequence after 5 i.e. 0100 is 1 for half step
cnt=0;
for(i=0; i<1; i++)
{
if(nhs==0)
break;
outb(0x40, BASEPORT);
if(++cnt==nhs)
break;
outb(0x60, BASEPORT);
if(++cnt==nhs)
break;
outb(0x20, BASEPORT);
if(++cnt==nhs)
break;
outb(0xA0, BASEPORT);
if(++cnt==nhs)
break;
outb(0x80, BASEPORT);
if(++cnt==nhs)
break;
outb(0x90, BASEPORT);
if(++cnt==nhs)
break;
outb(0x10, BASEPORT);
if(++cnt==nhs)
break;
//max of 7 half steps only possible
}
}
outb(0x00, BASEPORT);
}
void stepper::fwd(float len=0)
{
float tlen=len;
if(len==0)
return;
tlen=tlen+tlen*lcf/100;
length2steps(tlen, nfsc, nhs);
cout<<"\nMoving forward by "<<len<<"cms... \t[\t"<<nfsc<<" "<<nhs<<" ]"<<endl;
move(nfsc, nhs, 1, 1);//leftw=1 & rightw=1
}
void stepper::bkwd(float len=0)
{
float tlen=len;
if(len==0)
return;
tlen=tlen+tlen*lcf/100;
length2steps(tlen, nfsc, nhs);
cout<<"\nMoving backward by "<<len<<"cms... \t[\t"<<nfsc<<" "<<nhs<<" ]"<<endl;
move(nfsc, nhs, -1, -1);//leftw=-1 & rightw=-1
}
void stepper::lefturn(float angle, int dof=2) //degree of freedom
{
float tangle=angle;
tangle=tangle*2/dof;
tangle=tangle+tangle*acf/100;
angle2steps(tangle, nfsc, nhs);
cout<<"\nTaking left turn by "<<angle<<"degrees... [\t"<<nfsc<<" "<<nhs<<" ]"<<endl;
if(dof==1)
move(nfsc, nhs, 0, 1); //leftwheel=off, rightwheel=on
else
move(nfsc, nhs, -1, 1);
}
void stepper::righturn(float angle, int dof=2)
{
float tangle=angle;
tangle=tangle*2/dof;
tangle=tangle+tangle*acf/100;
angle2steps(tangle, nfsc, nhs);
cout<<"\nTaking right turn by "<<angle<<"degrees... [\t"<<nfsc<<" "<<nhs<<" ]"<<endl;
if(dof==1)
move(nfsc, nhs, 1, 0); //leftwheel=on, rightwheel=off
else
move(nfsc, nhs, 1, -1);
}
main()
{
system("clear");
if(ioperm(BASEPORT,3,1))
{
cout<<"\nThe parallel port accessing error!";
exit(1);
}
float speed; //in cm/s
float len, la, ra; //in cm
float angle;
long wait=10000;
//cout<<"\nEnter speed in cm/s (eg. 10cm/s) : ";
//cin>>speed;
speed=10;
stepper sm(speed);
sm.specification();
cout<<"\nScanning the problem...";usleep(wait);
cout<<"...";usleep(wait);cout<<"...";usleep(wait);cout<<"...";cout<<"Done!";
cout<<"\n\n\nStarting the voyage...\n\n\n";
float l1=20, l2=28.284;
float a1=45, a2=90, a3=135;
int i;
for(i=0; i<3; i++)
{
sm.fwd(l1);
usleep(wait);
sm.lefturn(a3);
usleep(wait);
sm.fwd(l2);
usleep(wait);
sm.righturn(a3);
}
}Macros to get and set a bit field within a value
// Get a bit field from a value
#define GetField(Var, Mask, Shift) \
(((Var) >> (Shift)) & (Mask))
// Set a bit field in a value
#define SetField(Var, Mask, Shift, Val) \
(Var) = (((Var) & ~((Mask) << (Shift))) | (((Val) & (Mask)) << (Shift)))Additive White Gaussian Noise Generator
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926536
double AWGN_generator()
{/* Generates additive white Gaussian Noise samples with zero mean and a standard deviation of 1. */
double temp1;
double temp2;
double result;
int p;
p = 1;
while( p > 0 )
{
temp2 = ( rand() / ( (double)RAND_MAX ) ); /* rand() function generates an
integer between 0 and RAND_MAX,
which is defined in stdlib.h.
*/
if ( temp2 == 0 )
{// temp2 is >= (RAND_MAX / 2)
p = 1;
}// end if
else
{// temp2 is < (RAND_MAX / 2)
p = -1;
}// end else
}// end while()
temp1 = cos( ( 2.0 * (double)PI ) * rand() / ( (double)RAND_MAX ) );
result = sqrt( -2.0 * log( temp2 ) ) * temp1;
return result; // return the generated random sample to the caller
}// end AWGN_generator()LCD, 4 bit data mode
/* note: lcd model MC21605A6W */
/* note: DB0:3 and RW must be grounded */
/* note: see https://github.com/texane/lcmeter for usage */
#include <stdint.h>
#include <avr/io.h>
#define LCD_POS_DB 0x02
#define LCD_PORT_DB PORTD
#define LCD_DIR_DB DDRD
#define LCD_MASK_DB (0x0f << LCD_POS_DB)
#define LCD_POS_EN 0x06
#define LCD_PORT_EN PORTD
#define LCD_DIR_EN DDRD
#define LCD_MASK_EN (0x01 << LCD_POS_EN)
#define LCD_POS_RS 0x07
#define LCD_PORT_RS PORTD
#define LCD_DIR_RS DDRD
#define LCD_MASK_RS (0x01 << LCD_POS_RS)
static inline void wait_50_ns(void)
{
__asm__ __volatile__ ("nop\n\t");
}
static inline void wait_500_ns(void)
{
/* 8 cycles at 16mhz */
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
}
static inline void wait_50_us(void)
{
/* 800 cycles at 16mhz */
uint8_t x;
for (x = 0; x < 100; ++x) wait_500_ns();
}
static inline void wait_2_ms(void)
{
wait_50_us();
wait_50_us();
wait_50_us();
wait_50_us();
}
static inline void wait_50_ms(void)
{
/* FIXME: was _delay_ms(50), but not working */
uint8_t x;
for (x = 0; x < 25; ++x) wait_2_ms();
}
static inline void lcd_pulse_en(void)
{
/* assume EN low */
LCD_PORT_EN |= LCD_MASK_EN;
wait_50_us();
LCD_PORT_EN &= ~LCD_MASK_EN;
wait_2_ms();
}
static void lcd_write_db4(uint8_t x)
{
/* configured in 4 bits mode */
LCD_PORT_DB &= ~LCD_MASK_DB;
LCD_PORT_DB |= (x >> 4) << LCD_POS_DB;
lcd_pulse_en();
LCD_PORT_DB &= ~LCD_MASK_DB;
LCD_PORT_DB |= (x & 0xf) << LCD_POS_DB;
lcd_pulse_en();
}
static void lcd_write_db8(uint8_t x)
{
/* configured in 8 bits mode */
/* only hi nibble transmitted, (0:3) grounded */
LCD_PORT_DB &= ~LCD_MASK_DB;
LCD_PORT_DB |= (x >> 4) << LCD_POS_DB;
lcd_pulse_en();
}
/* exported interface */
void lcd_setup(void)
{
LCD_DIR_DB |= LCD_MASK_DB;
LCD_DIR_RS |= LCD_MASK_RS;
LCD_DIR_EN |= LCD_MASK_EN;
LCD_PORT_DB &= ~LCD_MASK_DB;
LCD_PORT_RS &= ~LCD_MASK_RS;
LCD_PORT_EN &= ~LCD_MASK_EN;
/* small delay for the lcd to boot */
wait_50_ms();
/* datasheet init sequence */
#define LCD_MODE_BLINK (1 << 0)
#define LCD_MODE_CURSOR (1 << 1)
#define LCD_MODE_DISPLAY (1 << 2)
lcd_write_db8(0x30);
wait_2_ms();
wait_2_ms();
wait_500_ns();
lcd_write_db8(0x30);
wait_2_ms();
lcd_write_db4(0x32);
wait_2_ms();
lcd_write_db4(0x28);
wait_2_ms();
lcd_write_db4((1 << 3) | LCD_MODE_DISPLAY);
wait_2_ms();
lcd_write_db4(0x01);
wait_2_ms();
lcd_write_db4(0x0f);
wait_2_ms();
}
void lcd_clear(void)
{
/* clear lcd */
lcd_write_db4(0x01);
wait_2_ms();
}
void lcd_home(void)
{
/* set cursor to home */
lcd_write_db4(0x02);
wait_2_ms();
}
void lcd_set_ddram(uint8_t addr)
{
lcd_write_db4((1 << 7) | addr);
wait_2_ms();
}
void lcd_goto_xy(uint8_t x, uint8_t y)
{
/* assume 0 <= x < 8 */
/* assume 0 <= y < 2 */
/* from datasheet: */
/* first line is 0x00 to 0x27 */
/* second line is 0x40 to 0x67 */
static const uint8_t row[] = { 0x00, 0x40 };
lcd_set_ddram(row[y] | x);
}
void lcd_write(const uint8_t* s, unsigned int n)
{
wait_50_ns();
LCD_PORT_RS |= LCD_MASK_RS;
for (; n; --n, ++s)
{
lcd_write_db4(*s);
wait_2_ms();
}
LCD_PORT_RS &= ~LCD_MASK_RS;
}ADXL345 Driver
#define ADXL_SDA PIN_C4
#define ADXL_SCL PIN_C3
#define ADXL_CS PIN_C0
#use i2c(master, sda=ADXL_SDA, scl=ADXL_SCL)
void init_adxl345()
{
output_float(ADXL_SCL);
output_float(ADXL_SDA);
output_high(ADXL_CS);
}
BOOLEAN adxl345_ready()
{
int1 ack;
i2c_start(); // If the write command is acknowledged,
ack = i2c_write(0x3a); // then the device is ready.
i2c_stop();
return !ack;
}
void write_adxl345(BYTE address, BYTE data)
{
while(!adxl345_ready());
i2c_start();
i2c_write(0x3a);
i2c_write(address);
i2c_write(data);
i2c_stop();
}
BYTE read_adxl345(BYTE address)
{
BYTE data;
while(!adxl345_ready());
i2c_start();
i2c_write(0x3a);
i2c_write(address);
i2c_start();
i2c_write(0x3b);
data=i2c_read(0);
i2c_stop();
return(data);
}
int16 read_adxl345_axis(BYTE address)
{
BYTE msb,lsb;
while(!adxl345_ready());
i2c_start();
i2c_write(0x3a);
i2c_write(address);
i2c_start();
i2c_write(0x3b);
lsb=i2c_read(1);
msb=i2c_read(0);
i2c_stop();
return((msb<<8)|lsb);
}Plotting 16-bit binary data
%Script to load and plot 16-bit accelerometer data
printf "Running acceleration data analysis script\r\n"
clear * %Clear all variables
ts = (1/1000); %1KHz sampling rate
%Path to TXT file with accelerometer samples
accel_data_path = "accel_data.txt";
%Open the acceleration data file as read-only, binary mode
file_accel_data = fopen(accel_data_path,"rb");
%Read unit16 samples from TXT file into an array
%count is # of samples, val is array of values
[val,count] = fread(file_accel_data,Inf,"uint16");
fclose(file_accel_data);
%Generate a time vector from t=0 to the end determined by count and sampling time
tmax = (count-1)*ts;
t=0:ts:tmax;
%Open figure 1
figure(1)
%Plot accelerometer samples
plot(t,val','1')
%Make the plot look pretty
title("Raw Sampled Accelerometer Data")
xlabel("Time (s)")
ylabel("Accelerometer Data")
%Save the plot to disk
print("plots/raw_accel_data.png")Software SPI
#include<p16f877a.inc>
#define s_data_o PORTC,5 ;serial data out
#define s_data_i PORTC,4 ;serial data in
#define s_clock PORTC,3 ;clock out
udata_shr
tx_reg res 1
rx_reg res 1
code
;************************
;Configure I/O Ports
;Load data in WREG
;Call soft_spi_write
;************************
soft_spi_write
global soft_spi_write
banksel tx_reg
movwf tx_reg ;store W = tx_reg
banksel PORTC ;Bank 0
bsf STATUS,C ;Set Carry Flag=1
send_next_bit
rlf tx_reg,F ;rotate left
movf tx_reg,F ;Check wheter 8 bit transmitted or not
btfsc STATUS,Z ;If no ,send next bit
return ;if yes,return
bcf s_data_o ;data line low
btfsc STATUS,C ;check the bit in carry,
bsf s_data_o ;if high,s_data_o =1
fill (nop),3
bsf s_clock ;s_clock=1 | _
fill (nop),5 ; |clock high to low _| |_
bcf STATUS,C ;clear carry |
bcf s_clock ;S_clock=0 |
fill (nop),3
goto send_next_bit ; looping process...........
;**************************************************
;Configure I/O Ports
;Call soft_spi_read
;This fuction returns the received data is in WREG
;**************************************************
soft_spi_read ;subroutine for receive
global soft_spi_read
movlw 0x01 ;eight bit reception
movwf rx_reg
read_next_bit
rlf rx_reg,f ;rotating the rx_reg register to store the received bit
bsf s_clock
fill (nop),5
btfsc s_data_i
bsf rx_reg,0 ;receiving the data
bcf s_clock
fill (nop),3
btfss STATUS,C ;testing whether the reception is compleate or not
goto read_next_bit ;if not compleated do the process again
movf rx_reg,W ;restore data in WREG
return
endInterfacing SM630
#define cmd_add_fingerprint 0x40
#define cmd_search_fingerprint 0x44
#define cmd_packet 0x10
#define data_packet 0x20
#define res_packet 0x30
#define res_rcv_correct 0x01
#define res_rcv_error 0x02
#define res_opr_success 0x31
#define res_finger_detected 0x32
#define res_timeout 0x33
#define res_process_fail 0x34
#define res_para_error 0x35
#define res_fingerprint_found 0x39
#define res_fingerprint_unfound 0x3A
#use rs232(baud=57600,xmit=PIN_C6,rcv=PIN_C7,bits=8,parity=n,stop=1,stream=Finger,timeout=1000)//,force_sw)
int8 cmd_buffer[10],response_buffer[15];
int8 find_checksum(int8 total_byte)
{
int8 byte_count;
int16 check_sum=0;
for(byte_count=0;byte_count<total_byte;byte_count++)
{
check_sum+=cmd_buffer[byte_count];
}
return(make8(check_sum,0));
}
void cmd_to_sm630(int8 total_byte)
{
int8 byte_count;
for(byte_count=0;byte_count<total_byte;byte_count++)
{
fputc(cmd_buffer[byte_count],Finger);
delay_us(10);
}
}
void response_from_sm630(int8 total_byte)
{
int8 byte_count;
while(fgetc(Finger)!=0x4D);
response_buffer[0]=0x4D;
for(byte_count=1;byte_count<total_byte;byte_count++)
{
response_buffer[byte_count]=fgetc(Finger);
}
}
int8 add_finger(int16 finger_id)
{
cmd_buffer[0]=0x4D; //Packet Head
cmd_buffer[1]=0x58; //Packet Head
cmd_buffer[2]=cmd_packet; //Command Packet
cmd_buffer[3]=0x03; //3 byte length
cmd_buffer[4]=cmd_add_fingerprint; //Add finger Print cmd
cmd_buffer[5]=make8(finger_id,1);//Higher byte of finger print id
cmd_buffer[6]=make8(finger_id,0);//Lower byte of finger print id
cmd_buffer[7]=find_checksum(7);//Check sum of 7 bytes
cmd_to_sm630(8);
response_from_sm630(6); //Read 6 bytes
if(response_buffer[4] == res_rcv_correct)
{
response_from_sm630(7); //Read 6 bytes
if(response_buffer[5] == res_opr_success)
{
//Display Press finger again
//lcd_goto(2,1);
//lcd_send_byte(" Press again ");
response_from_sm630(7); //Read 6 bytes
}
}
return (response_buffer[5]);
}
int8 search_finger(int16& result_id,int16 num_fingerprint)
{
output_low(PIN_A5);
cmd_buffer[0]=0x4D; //Packet Head
cmd_buffer[1]=0x58; //Packet Head
cmd_buffer[2]=cmd_packet; //Command Packet
cmd_buffer[3]=0x05; //5 byte length
cmd_buffer[4]=cmd_search_fingerprint; //Search finger Print cmd
cmd_buffer[5]=0x00; //Higher byte of Starting id
cmd_buffer[6]=0x00; //Lower byte of Starting id
cmd_buffer[7]=make8(num_fingerprint,1);//Higher byte of number of fingerprints searched
cmd_buffer[8]=make8(num_fingerprint,0);//Lower byte of number of fingerprints searched
cmd_buffer[9]=find_checksum(9);//Check sum of 9 bytes
cmd_to_sm630(10);
response_from_sm630(6); //Read 6 bytes
if(response_buffer[4] == res_rcv_correct)
{
response_from_sm630(7); //Read 7 bytes
if(response_buffer[5] == res_opr_success)
{
delay_ms(10);
response_from_sm630(6); //Read 6 bytes
//disp_response(6);
if(response_buffer[5] == res_fingerprint_found)
{
response_buffer[0]=fgetc(Finger);
response_buffer[1]=fgetc(Finger);
result_id=make16(response_buffer[0],response_buffer[1]);
}
}
}
else
response_buffer[5]=response_buffer[4];
return (response_buffer[5]);
}soft Real Time Clock implementation
typedef struct t_smalltm{
u16 year;
u8 mon;
u8 day;
u8 hour;
u8 min;
u8 sec;
} t_smalltm;
t_smalltm rtc;
//**************************************************************
// call this function every 1 sec. from timer interrupt.
// for fast code execution rtc will be placed in internal RAM.
//**************************************************************
void realTimeClock(void)
{u8 rest;
if (++rtc.sec==60) // sec
{
rtc.sec=0;
if (++rtc.min==60) // min
{
rtc.min=0;
if (++rtc.hour==24) // hour
{
rtc.hour=0;
rtc.day++; // day
rest=rtc.year%4;
if ((((rest==0 && rtc.year%100!=0) || rtc.year%400==0)
&& rtc.mon==2 && rtc.day==30)
|| (rest && rtc.mon==2 && rtc.day==29)
|| ((rtc.mon==4 || rtc.mon==6 || rtc.mon==9 || rtc.mon==11)
&& rtc.day==31)
|| (rtc.day==32))
{
rtc.day=1;
if (++rtc.mon==13) // mon
rtc.mon=1, rtc.year++; // HAPPY NEW YEAR ! :)
}
}
}
}
}
//**************************************************************
// read RTC function
void getRTC(t_smalltm* stm)
{
disableInterrupts(); // evite erronated read
// because realTimeClock is called from interrupt
memcpy(stm,&rtc,sizeof(t_smalltm));
enableInterrupts();
}
//**************************************************************
// set RTC function
void setRTC(u16 year, u8 mon, u8 day, u8 hour, u8 min, u8 sec)
{
disableInterrupts();
rtc.year=year;
rtc.mon=mon;
rtc.day=day;
rtc.hour=hour;
rtc.min=min;
rtc.sec=sec;
enableInterrupts();
}Additive White Gaussian Noise Generator
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926536
double AWGN_generator()
{/* Generates additive white Gaussian Noise samples with zero mean and a standard deviation of 1. */
double temp1;
double temp2;
double result;
int p;
p = 1;
while( p > 0 )
{
temp2 = ( rand() / ( (double)RAND_MAX ) ); /* rand() function generates an
integer between 0 and RAND_MAX,
which is defined in stdlib.h.
*/
if ( temp2 == 0 )
{// temp2 is >= (RAND_MAX / 2)
p = 1;
}// end if
else
{// temp2 is < (RAND_MAX / 2)
p = -1;
}// end else
}// end while()
temp1 = cos( ( 2.0 * (double)PI ) * rand() / ( (double)RAND_MAX ) );
result = sqrt( -2.0 * log( temp2 ) ) * temp1;
return result; // return the generated random sample to the caller
}// end AWGN_generator()Stepper motor controller for precise movement
/*
* IBM-PC Parallel Printer Port Data & Status Registers
* ====================================================
* 7 6 5 4 3 2 1 0 I/O Port
* +---+---+---+---+---+---+---+---+ ========
* Data | C8| C7| C6| C5| C4| C3| C2| C1| Base = 278/378/3BC Hex
* +---+---+---+---+---+---+---+---+ +---+
*/
#include<sys/io.h>
#include<unistd.h>
#include<stdlib.h>
#include<math.h> //for floor()
#include<iostream>
using namespace std;
#define BASEPORT 0x378 //SPP - Standard Parallel port base address
class stepper
{
private:
long delay; //delay betn each step
float pi; //constant
float acf, lcf; //angle and length correction factors in percentage
float r, c; // radius and circumerence of wheel
float ns;
int nfsc, nhs;
float residue;
// number of total steps, full step cycles and number of half steps
float step_rating; //number of steps per revolution
float speed; //speed of stepper in cm/sec
float l,w; //length and width of robocar
public:
stepper(float spd);
void specification();
void length2steps(float len, int& nfsc, int& nhs);//conversion
void angle2steps(float angle, int& nfsc, int& nhs);//conversion
void move(int nfsc, int nhs, int leftw, int rightw); //move
void fwd(float len); //length in cm
void bkwd(float len); //length in cm
void righturn(float degree, int degree_of_freedom); //number of degree turns
void lefturn(float degree, int degree_of_freedom); // -- do --
};
stepper:: stepper(float spd=7)
{
speed=spd;
l=18; //length of car
w=17-2; //width of car
acf=-2; //angle correction factor in percentage
lcf=-4; //angle correction factor in percentage
pi=3.14159; //costant
step_rating=200.5; //step rating
r=3.448; //radius of wheel in cm
c=2*pi*r; //circumference
residue=0;
//speed being in cm/s
delay=long(1/(step_rating/c*speed)*1000*1000); //in microsecond
}
void stepper::specification()
{
cout<<"\n\n\n\t\tF R O N T I E R\n";
cout<<"\t~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
cout<<"\n\n\nDesigned by: Amit Kumar Karna";
cout<<"\n\n\nMission: Vitrubio, Technozion'06 @ NIT Warangal";
cout<<"\n\n\nROBOCAR specifications...";
cout<<"\nDimensions = "<<l<<"cm x"<<w<<"cm";
cout<<"\nWheel Dia = "<<2*r<<"cm";
cout<<"\nStepper motor: 12V-0.33A \t"<<step_rating<<" steps/revolution";
cout<<"\nLength n Angle correction factors: "<<lcf<<"% & "<<acf<<"% respectively";
cout<<"\nSpeed selected : "<<speed<<"cm/sec";
cout<<"\ndelay between each step = "<<delay/1000.0<<"ms";
cout<<endl<<endl<<endl;
}
void stepper::length2steps(float len, int& nfsc, int& nhs)//conversion
{
ns=step_rating/c*len+residue;
nfsc=int(ns/4);
nhs=int(floor((ns-nfsc*4)/0.5)); //rounding
if(nhs==8) //may result after rounding
nhs=7;
residue=ns-(nfsc*4+nhs*0.5);
}
void stepper::angle2steps(float angle, int& nfsc, int& nhs)//conversion
{
float arclen=(pi*w)/360.0*angle;
length2steps(arclen, nfsc, nhs);
}
void stepper::move(int nfsc, int nhs, int leftw, int rightw) //move
{
int i;
int cnt;
outb(0x00, BASEPORT);
if(leftw==1 && rightw==1)
{
for(i=0; i<nfsc; i++)
{
outb(0x59, BASEPORT);
usleep(delay);
outb(0x6A, BASEPORT);
usleep(delay);
outb(0xA6, BASEPORT);
usleep(delay);
outb(0x95, BASEPORT);
usleep(delay);
if(i%50==0 && i!=0)
outb(0x81, BASEPORT); //one half step - as a compensation
}
//sequence after 5 i.e. 0100 is 1 for half step
//sequence after 9 i.e. 1001 is 8 for half step
for(i=0; i<1; i++) //dummy loop to use break;
{
cnt=0;
if(nhs==0)
break;
outb(0x81, BASEPORT);
if(++cnt==nhs)
break;
outb(0xA9, BASEPORT);
if(++cnt==nhs)
break;
outb(0x28, BASEPORT);
if(++cnt==nhs)
break;
outb(0x6A, BASEPORT);
if(++cnt==nhs)
break;
outb(0x42, BASEPORT);
if(++cnt==nhs)
break;
outb(0x56, BASEPORT);
if(++cnt==nhs)
break;
outb(0x14, BASEPORT);
if(++cnt==nhs)
break;
//max of 7 half steps only possible
}
}
else if(leftw==-1 && rightw==-1)
{
for(i=0; i<nfsc; i++)
{
outb(0x95, BASEPORT);
usleep(delay);
outb(0xA6, BASEPORT);
usleep(delay);
outb(0x6A, BASEPORT);
usleep(delay);
outb(0x59, BASEPORT);
usleep(delay);
if(i%50==0 && i!=0)
outb(0x81, BASEPORT); //one half step - as a compensation
}
//sequence after 5 i.e. 0100 is 1 for half step
//sequence after 9 i.e. 1001 is 8 for half step
for(i=0; i<1; i++) //dummy loop
{
cnt=0;
if(nhs==0)
break;
outb(0x81, BASEPORT);
if(++cnt==nhs)
break;
outb(0xA9, BASEPORT);
if(++cnt==nhs)
break;
outb(0x28, BASEPORT);
if(++cnt==nhs)
break;
outb(0x6A, BASEPORT);
if(++cnt==nhs)
break;
outb(0x42, BASEPORT);
if(++cnt==nhs)
break;
outb(0x56, BASEPORT);
if(++cnt==nhs)
break;
outb(0x14, BASEPORT);
if(++cnt==nhs)
break;
}
}
else if(leftw==-1 && rightw==1) //left turn 2 wheels
{
for(i=0;i<nfsc;i++)
{
outb(0x99, BASEPORT);
usleep(delay);
outb(0xAA, BASEPORT);
usleep(delay);
outb(0x66, BASEPORT);
usleep(delay);
outb(0x55, BASEPORT);
usleep(delay);
}
//sequence after 5 i.e. 0100 is 1 for half step
cnt=0;
for(i=0; i<1; i++)
{
if(nhs==0)
break;
outb(0x11, BASEPORT);
if(++cnt==nhs)
break;
outb(0x99, BASEPORT);
if(++cnt==nhs)
break;
outb(0x88, BASEPORT);
if(++cnt==nhs)
break;
outb(0xAA, BASEPORT);
if(++cnt==nhs)
break;
outb(0x22, BASEPORT);
if(++cnt==nhs)
break;
outb(0x66, BASEPORT);
if(++cnt==nhs)
break;
outb(0x44, BASEPORT);
if(++cnt==nhs)
break;
//max of 7 half steps only possible
}
}
else if(leftw==1 && rightw==-1) //right turn with 2 wheels
{
for(i=0;i<nfsc;i++)
{
outb(0x55, BASEPORT);
usleep(delay);
outb(0x66, BASEPORT);
usleep(delay);
outb(0xAA, BASEPORT);
usleep(delay);
outb(0x99, BASEPORT);
usleep(delay);
}
//sequence after 5 i.e. 0100 is 1 for half step
cnt=0;
for(i=0; i<1; i++)
{
if(nhs==0)
break;
outb(0x44, BASEPORT);
if(++cnt==nhs)
break;
outb(0x66, BASEPORT);
if(++cnt==nhs)
break;
outb(0x22, BASEPORT);
if(++cnt==nhs)
break;
outb(0xAA, BASEPORT);
if(++cnt==nhs)
break;
outb(0x88, BASEPORT);
if(++cnt==nhs)
break;
outb(0x99, BASEPORT);
if(++cnt==nhs)
break;
outb(0x11, BASEPORT);
if(++cnt==nhs)
break;
//max of 7 half steps only possible
}
}
else if(leftw==0 && rightw==1) //left turn with one wheel
{
for(i=0;i<nfsc;i++)
{
outb(0x09, BASEPORT);
usleep(delay);
outb(0x0A, BASEPORT);
usleep(delay);
outb(0x06, BASEPORT);
usleep(delay);
outb(0x05, BASEPORT);
usleep(delay);
}
//sequence after 5 i.e. 0100 is 1 for half step
cnt=0;
for(i=0; i<1; i++)
{
if(nhs==0)
break;
outb(0x01, BASEPORT);
if(++cnt==nhs)
break;
outb(0x09, BASEPORT);
if(++cnt==nhs)
break;
outb(0x08, BASEPORT);
if(++cnt==nhs)
break;
outb(0x0A, BASEPORT);
if(++cnt==nhs)
break;
outb(0x02, BASEPORT);
if(++cnt==nhs)
break;
outb(0x06, BASEPORT);
if(++cnt==nhs)
break;
outb(0x04, BASEPORT);
if(++cnt==nhs)
break;
//max of 7 half steps only possible
}
}
else if(leftw==1 && rightw==0) //right turn with one wheel
{
for(i=0;i<nfsc;i++)
{
outb(0x50, BASEPORT);
usleep(delay);
outb(0x60, BASEPORT);
usleep(delay);
outb(0xA0, BASEPORT);
usleep(delay);
outb(0x90, BASEPORT);
usleep(delay);
}
//sequence after 5 i.e. 0100 is 1 for half step
cnt=0;
for(i=0; i<1; i++)
{
if(nhs==0)
break;
outb(0x40, BASEPORT);
if(++cnt==nhs)
break;
outb(0x60, BASEPORT);
if(++cnt==nhs)
break;
outb(0x20, BASEPORT);
if(++cnt==nhs)
break;
outb(0xA0, BASEPORT);
if(++cnt==nhs)
break;
outb(0x80, BASEPORT);
if(++cnt==nhs)
break;
outb(0x90, BASEPORT);
if(++cnt==nhs)
break;
outb(0x10, BASEPORT);
if(++cnt==nhs)
break;
//max of 7 half steps only possible
}
}
outb(0x00, BASEPORT);
}
void stepper::fwd(float len=0)
{
float tlen=len;
if(len==0)
return;
tlen=tlen+tlen*lcf/100;
length2steps(tlen, nfsc, nhs);
cout<<"\nMoving forward by "<<len<<"cms... \t[\t"<<nfsc<<" "<<nhs<<" ]"<<endl;
move(nfsc, nhs, 1, 1);//leftw=1 & rightw=1
}
void stepper::bkwd(float len=0)
{
float tlen=len;
if(len==0)
return;
tlen=tlen+tlen*lcf/100;
length2steps(tlen, nfsc, nhs);
cout<<"\nMoving backward by "<<len<<"cms... \t[\t"<<nfsc<<" "<<nhs<<" ]"<<endl;
move(nfsc, nhs, -1, -1);//leftw=-1 & rightw=-1
}
void stepper::lefturn(float angle, int dof=2) //degree of freedom
{
float tangle=angle;
tangle=tangle*2/dof;
tangle=tangle+tangle*acf/100;
angle2steps(tangle, nfsc, nhs);
cout<<"\nTaking left turn by "<<angle<<"degrees... [\t"<<nfsc<<" "<<nhs<<" ]"<<endl;
if(dof==1)
move(nfsc, nhs, 0, 1); //leftwheel=off, rightwheel=on
else
move(nfsc, nhs, -1, 1);
}
void stepper::righturn(float angle, int dof=2)
{
float tangle=angle;
tangle=tangle*2/dof;
tangle=tangle+tangle*acf/100;
angle2steps(tangle, nfsc, nhs);
cout<<"\nTaking right turn by "<<angle<<"degrees... [\t"<<nfsc<<" "<<nhs<<" ]"<<endl;
if(dof==1)
move(nfsc, nhs, 1, 0); //leftwheel=on, rightwheel=off
else
move(nfsc, nhs, 1, -1);
}
main()
{
system("clear");
if(ioperm(BASEPORT,3,1))
{
cout<<"\nThe parallel port accessing error!";
exit(1);
}
float speed; //in cm/s
float len, la, ra; //in cm
float angle;
long wait=10000;
//cout<<"\nEnter speed in cm/s (eg. 10cm/s) : ";
//cin>>speed;
speed=10;
stepper sm(speed);
sm.specification();
cout<<"\nScanning the problem...";usleep(wait);
cout<<"...";usleep(wait);cout<<"...";usleep(wait);cout<<"...";cout<<"Done!";
cout<<"\n\n\nStarting the voyage...\n\n\n";
float l1=20, l2=28.284;
float a1=45, a2=90, a3=135;
int i;
for(i=0; i<3; i++)
{
sm.fwd(l1);
usleep(wait);
sm.lefturn(a3);
usleep(wait);
sm.fwd(l2);
usleep(wait);
sm.righturn(a3);
}
}base64 Encoding
#include <string.h>
#include <stdint.h>
//This is a helper function to convert a six-bit value to base64
char base64_encode_six(uint8_t six_bit_value){
uint8_t x;
char c;
x = six_bit_value & ~0xC0; //remove top two bits (should be zero anyway)
if( x < 26 ){
c = 'A' + x;
} else if ( x < 52 ){
c = 'a' + (x - 26);
} else if( x < 62 ){
c = '0' + (x - 52);
} else if( x == 62 ){
c = '+';
} else if (x == 63 ){
c = '/';
} else {
printf("ERROR IN BASE 64\n");
c = 'A';
}
return c;
}
//This is the function for encoding in base64
void base64_encode(char * dest, const char * src){
int bits;
int i;
int j;
int k;
int len;
uint8_t six_bits[4];
len = strlen(src);
k = 0;
//We need to encode three bytes at a time in to four encoded bytes
for(i=0; i < len; i+=3){
//First the thress bytes are broken down into six-bit sections
six_bits[0] = (src[i] >> 2) & 0x3F;
six_bits[1] = ((src[i] << 4) & 0x30) + ((src[i+1]>>4) & 0x0F);
six_bits[2] = ((src[i+1] << 2) & 0x3C) + ((src[i+2]>>6) & 0x03);
six_bits[3] = src[i+2] & 0x3F;
//now we use the helper function to convert from six-bits to base64
for(j=0; j < 4; j++){
dest[k+j] = base64_encode_six(six_bits[j]);
}
k+=4;
}
//at the end, we add = if the input is not divisible by 3
if( (len % 3) == 1 ){
//two equals at end
dest[k-2] = '=';
dest[k-1] = '=';
} else if ( (len %3 ) == 2 ){
dest[k-1] = '=';
}
//finally, zero terminate the output string
dest[k] = 0;
}Graphics in source code
// This enum defines the value of each of the 256 possible combinations of
// underlines and Os in 8 bits.
enum
{
________,_______O,______O_,______OO,_____O__,_____O_O,_____OO_,_____OOO,
____O___,____O__O,____O_O_,____O_OO,____OO__,____OO_O,____OOO_,____OOOO,
___O____,___O___O,___O__O_,___O__OO,___O_O__,___O_O_O,___O_OO_,___O_OOO,
___OO___,___OO__O,___OO_O_,___OO_OO,___OOO__,___OOO_O,___OOOO_,___OOOOO,
__O_____,__O____O,__O___O_,__O___OO,__O__O__,__O__O_O,__O__OO_,__O__OOO,
__O_O___,__O_O__O,__O_O_O_,__O_O_OO,__O_OO__,__O_OO_O,__O_OOO_,__O_OOOO,
__OO____,__OO___O,__OO__O_,__OO__OO,__OO_O__,__OO_O_O,__OO_OO_,__OO_OOO,
__OOO___,__OOO__O,__OOO_O_,__OOO_OO,__OOOO__,__OOOO_O,__OOOOO_,__OOOOOO,
_O______,_O_____O,_O____O_,_O____OO,_O___O__,_O___O_O,_O___OO_,_O___OOO,
_O__O___,_O__O__O,_O__O_O_,_O__O_OO,_O__OO__,_O__OO_O,_O__OOO_,_O__OOOO,
_O_O____,_O_O___O,_O_O__O_,_O_O__OO,_O_O_O__,_O_O_O_O,_O_O_OO_,_O_O_OOO,
_O_OO___,_O_OO__O,_O_OO_O_,_O_OO_OO,_O_OOO__,_O_OOO_O,_O_OOOO_,_O_OOOOO,
_OO_____,_OO____O,_OO___O_,_OO___OO,_OO__O__,_OO__O_O,_OO__OO_,_OO__OOO,
_OO_O___,_OO_O__O,_OO_O_O_,_OO_O_OO,_OO_OO__,_OO_OO_O,_OO_OOO_,_OO_OOOO,
_OOO____,_OOO___O,_OOO__O_,_OOO__OO,_OOO_O__,_OOO_O_O,_OOO_OO_,_OOO_OOO,
_OOOO___,_OOOO__O,_OOOO_O_,_OOOO_OO,_OOOOO__,_OOOOO_O,_OOOOOO_,_OOOOOOO,
O_______,O______O,O_____O_,O_____OO,O____O__,O____O_O,O____OO_,O____OOO,
O___O___,O___O__O,O___O_O_,O___O_OO,O___OO__,O___OO_O,O___OOO_,O___OOOO,
O__O____,O__O___O,O__O__O_,O__O__OO,O__O_O__,O__O_O_O,O__O_OO_,O__O_OOO,
O__OO___,O__OO__O,O__OO_O_,O__OO_OO,O__OOO__,O__OOO_O,O__OOOO_,O__OOOOO,
O_O_____,O_O____O,O_O___O_,O_O___OO,O_O__O__,O_O__O_O,O_O__OO_,O_O__OOO,
O_O_O___,O_O_O__O,O_O_O_O_,O_O_O_OO,O_O_OO__,O_O_OO_O,O_O_OOO_,O_O_OOOO,
O_OO____,O_OO___O,O_OO__O_,O_OO__OO,O_OO_O__,O_OO_O_O,O_OO_OO_,O_OO_OOO,
O_OOO___,O_OOO__O,O_OOO_O_,O_OOO_OO,O_OOOO__,O_OOOO_O,O_OOOOO_,O_OOOOOO,
OO______,OO_____O,OO____O_,OO____OO,OO___O__,OO___O_O,OO___OO_,OO___OOO,
OO__O___,OO__O__O,OO__O_O_,OO__O_OO,OO__OO__,OO__OO_O,OO__OOO_,OO__OOOO,
OO_O____,OO_O___O,OO_O__O_,OO_O__OO,OO_O_O__,OO_O_O_O,OO_O_OO_,OO_O_OOO,
OO_OO___,OO_OO__O,OO_OO_O_,OO_OO_OO,OO_OOO__,OO_OOO_O,OO_OOOO_,OO_OOOOO,
OOO_____,OOO____O,OOO___O_,OOO___OO,OOO__O__,OOO__O_O,OOO__OO_,OOO__OOO,
OOO_O___,OOO_O__O,OOO_O_O_,OOO_O_OO,OOO_OO__,OOO_OO_O,OOO_OOO_,OOO_OOOO,
OOOO____,OOOO___O,OOOO__O_,OOOO__OO,OOOO_O__,OOOO_O_O,OOOO_OO_,OOOO_OOO,
OOOOO___,OOOOO__O,OOOOO_O_,OOOOO_OO,OOOOOO__,OOOOOO_O,OOOOOOO_,OOOOOOOO,
};
// These macros use the above enum to build the image in a source file.
#define G8(n0) (n0) //!< Build a byte image line
#define G16(n1, n0) (((n1) << 8) | (n0))
//!< Build a halfword image line
#define G32(n3, n2, n1, n0) \
((G16 ((n3), (n2)) << 16) | G16 ((n1), (n0)))
//!< Build a word image line
#define G64(n7, n6, n5, n4, n3, n2, n1, n0) \
((G32 ((n7), (n6), (n5), (n4)) << 32) | G32 ((n3), (n2), (n1), (n0)))
//!< Build a long image line
=====
Example using the letter A in Arial Black 21 font:
Old code:
{
19, // A
0x00040000, 0x00078000, 0x0007F000, 0x0007FC00,
0x0007FF80, 0x0003FFF0, 0x0000FFFC, 0x0000FFFE,
0x0000F1FE, 0x0000F03E, 0x0000F1FE, 0x0000FFFE,
0x0000FFFC, 0x0003FFF0, 0x0007FF80, 0x0007FC00,
0x0007F000, 0x00078000, 0x00040000
};
New code:
{
19, // A
G32 (________,_____O__,________,________),
G32 (________,_____OOO,O_______,________),
G32 (________,_____OOO,OOOO____,________),
G32 (________,_____OOO,OOOOOO__,________),
G32 (________,_____OOO,OOOOOOOO,O_______),
G32 (________,______OO,OOOOOOOO,OOOO____),
G32 (________,________,OOOOOOOO,OOOOOO__),
G32 (________,________,OOOOOOOO,OOOOOOO_),
G32 (________,________,OOOO___O,OOOOOOO_),
G32 (________,________,OOOO____,__OOOOO_),
G32 (________,________,OOOO___O,OOOOOOO_),
G32 (________,________,OOOOOOOO,OOOOOOO_),
G32 (________,________,OOOOOOOO,OOOOOO__),
G32 (________,______OO,OOOOOOOO,OOOO____),
G32 (________,_____OOO,OOOOOOOO,O_______),
G32 (________,_____OOO,OOOOOO__,________),
G32 (________,_____OOO,OOOO____,________),
G32 (________,_____OOO,O_______,________),
G32 (________,_____O__,________,________),
};Binary numbers
// The following macros build values in binary. Nybbles are separated by
// commas for readability. If a non-binary digit is used, a compiler error
// will result. Here are some examples of the usage of the binary macros:
//
// B4 (0110) = 0x06
// B8 (0101,0101) = 0x55
// B16 (1010,1010, 0101,0101) = 0xAA55
// B32 (1000,0000, 1111,1111, 1010,1010, 0101,0101) = 0x80FFAA55
//
// For maximum readability, the bytes should be separated by spaces and there
// should be no spaces between nybbles, as shown above. Note that an enum
// isn't used because MISRA-C generates errors otherwise.
#define b0000 0u
#define b0001 1u
#define b0010 2u
#define b0011 3u
#define b0100 4u
#define b0101 5u
#define b0110 6u
#define b0111 7u
#define b1000 8u
#define b1001 9u
#define b1010 10u
#define b1011 11u
#define b1100 12u
#define b1101 13u
#define b1110 14u
#define b1111 15u
#pragma diag_suppress = Pm120
#define B4(n0) (b##n0) //!< Build a nybble in binary
#pragma diag_default = Pm120
#define B8(n1, n0) ((B4 (n1) << 4u) | B4 (n0))
//!< Build a byte in binary
#define B16(n3, n2, n1, n0) \
((B4 (n3) << 12) | (B4 (n2) << 8) | (B4 (n1) << 4) | B4 (n0))
//!< Build a halfword in binary
#define B32(n7, n6, n5, n4, n3, n2, n1, n0) \
((B4 (n7) << 28) | (B4 (n6) << 24) | (B4 (n5) << 20) | (B4 (n5) << 16) \
| (B4 (n3) << 12) | (B4 (n2) << 8) | (B4 (n1) << 4) | B4 (n0))
//!< Build a word in binary
#define B64(nF, nE, nD, nC, nB, nA, n9, n8, n7, n6, n5, n4, n3, n2, n1, n0) \
((B4 (nF) << 60) | (B4 (nE) << 56) | (B4 (nD) << 52) | (B4 (nC) << 48) \
| (B4 (nB) << 44) | (B4 (nA) << 40) | (B4 (n9) << 36) | (B4 (n8) << 32) \
| (B4 (n7) << 28) | (B4 (n6) << 24) | (B4 (n5) << 20) | (B4 (n5) << 16) \
| (B4 (n3) << 12) | (B4 (n2) << 8) | (B4 (n1) << 4) | B4 (n0))
//!< Build a long in binaryLittle Endian Converter Functions
unsigned short u16ToLittleEndian( unsigned short u16input )
{/* Use this function to convert a 16-bit number into little endian. */
return( (u16input >> 8) ^ (u16input << 8) );
}// end u16ToLittleEndian()
unsigned long u32ToLittleEndian( unsigned long u32input )
{/* Use this function to convert a 32-bit number into little endian. */
return( (u32input >> 24)
^ ( (u32input >> 8) & 0x000FF00 )
^ ( (u32input << 8) & 0x00FF0000 )
^ ( (u32input << 24) & 0xFF000000 )
);
}// end u32ToLittleEndian()Exponential Moving Average
//This macros defines an alpha value between 0 and 1
#define DSP_EMA_I32_ALPHA(x) ( (uint16_t)(x * 65535) )
int32_t dsp_ema_i32(int32_t in, int32_t average, uint16_t alpha){
int64_t tmp0; //calcs must be done in 64-bit math to avoid overflow
tmp0 = (int64_t)in * (alpha) + (int64_t)average * (65536 - alpha);
return (int32_t)((tmp0 + 32768) / 65536); //scale back to 32-bit (with rounding)
}
//here is a function that uses the averaging code
int32_t my_avg_func(void){
static int32_t average = 0;
int32_t adc_value;
adc_value = read_the_adc_value();
average = dsp_ema_i32(adc_value, average, DSP_EMA_I32_ALPHA(0.1));
return average;
}Binary Coded Decimal (BCD) - ASCII Converter
char bcdToAscii( unsigned char bcdNibble )
{
char result;
if( bcdNibble < 10 )
{// valid BCD input. ( [0,9] is the valid range for BCD input. )
result = (char)( bcdNibble + 48 ); // +48 is applicable to [0,9] input range.
}// end if
else
{// invalid input
result = '0';
}// end else
return( result );
}// end bcdToAscii()
unsigned char asciiToBcd( char asciiByte )
{/* Converts an input ASCII character (expected within the [ '0' - '9' ] range) into its BCD counterpart. */
unsigned char result;
if(
asciiByte >= '0'
&& asciiByte <= '9'
)
{// range check passed.
result = (unsigned char)(asciiByte - 48); // -48 offset gives the decimal value of the ASCII character.
}
else
{// range check failed.
result = 0;
}// end else
return( result );
}// end asciiToBcd()Embedded Linux Frequency Meter
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/arch/gpio.h>
#include <asm/arch/dmtimer.h>
/*
The prescaler is enabled when TCLR bit 5 is set (PRE). The 2n division ratio value
(PTV) can be configured in the TCLR register.
Each internal interrupt source can be independently enabled/disabled in the interrupt
enable register TIER.
When the interrupt event has been issued, the associated interrupt status bit is set
in the timer status register (TISR). The pending interrupt event is reset when the
set status bit is overwritten by a 1.
The timer rate is defined by:
-Value of the prescaler fields (PRE and PTV of TCLR register)
-Value loaded into the timer load register (TLDR)
timer rate = (0xFFFF FFFF – TLDR + 1) x timer clock period x clock divider (PS)
PTV + 1)
PS = 2
*/
static unsigned long freq , ct, round;
extern struct omap_dm_timer * frequencimeter; // timer reserved to measure frequency
static irqreturn_t gpio4_freqmeter_irq_handler(int irq, void *arg);
static int __init freqmeter_init(void)
{
int r;
round = 0; freq = 0 ; ct = 0;
printk(KERN_DEBUG "Init driver Freqmeter.\n");
/* request gpios*/
/* GPIO - P20_1610_GPIO4 */
if ( omap_request_gpio(4) < 0 ) printk(KERN_ERR "Error init GPIO4 (freqmeter).\n");
/* entrada */
omap_set_gpio_direction(4,1); /* in */
r = request_irq(OMAP_GPIO_IRQ(4), gpio4_freqmeter_irq_handler, IRQF_TRIGGER_RISING, "freqmeter", gpio4_freqmeter_irq_handler);
if ( r < 0 ) {
printk(KERN_ERR "freqmeter: request_irq() failed.\n");
return r;
}
printk(KERN_DEBUG "freqmeter initialized.\n");
return 0;
}
static irqreturn_t gpio4_freqmeter_irq_handler(int irq, void *arg)
{
// dummy: no interrupt? freq = 0Hz
// only one int? freq = 0Hz
/** there is interference?: lread INT again
should be in same logic level */
if ( omap_get_gpio_datain(4) )
{
if(round > 0)
{
if(round == 50)
{
ct = omap_dm_timer_read_counter(frequencimeter);
omap_dm_timer_stop(frequencimeter);
ct /= 50;
freq = 1200000000/(ct +1);
printk("freq = %d\n",(freq/*-8*/));
round = 0xFFFFFFFF;
ct = 0;
freq = 0;
}
}
else // first read
{
freq = 0;
printk(KERN_DEBUG "Iniciou o freqmeter");
omap_dm_timer_write_counter(frequencimeter,0x0);
omap_dm_timer_start(frequencimeter);
}
round++;
}
return IRQ_HANDLED;
}
asmlinkage long sys_freq_read(void)
{
return freq;
}
static void __exit freqmeter_cleanup(void)
{
free_irq(OMAP_GPIO_IRQ(4), NULL);
omap_free_gpio(4);
}
module_init(freqmeter_init);
module_exit(freqmeter_cleanup);
MODULE_LICENSE("GPL");Integer to ASCII
/***** integerToAscii.h *****/
#define BASE_OCTAL 8
#define BASE_DECIMAL 10
#define BASE_HEXADECIMAL 16
#define BUFFER_SIZE 32
char* integerToASCII(long int value, int base);
/***** integerToAscii.c *****/
char* integerToASCII(long int value, int base){
int aux;
static char buf[BUFFER_SIZE] = {0};
int isNeg=0;
if (value == 0) {
buf[0]='0';
return &buf[0];
}
if (value<0) {
isNeg = 1;
value *= -1;
}
for(aux=BUFFER_SIZE; value && aux ; --aux, value /= base){
buf[aux] = "0123456789abcdef"[value % base];
}
if (isNeg) {
buf[aux] = '-';
return &buf[aux];
}
return &buf[aux+1];
}






