โครงงานที่ 3
ดาวโหลดซอร์ดโค๊ด
***สำหรับไฟล์
Sms_Char.hex
เป็นชุดอักษรที่ต้องโปรแกรมไปไว้ที่ส่วนของ
EEPROM ของ AVR ก่อน
เรื่องใช้มือถือ
NOKIA เก่า ๆ ให้เป็นยาม
แนวความคิด
วันหนึ่งผมได้มีโอกาสไปช็อปปิ้งที่ศูนย์การค้าแห่งหนึ่งในจังหวัดพิษณุโลก
เผอิญวันนั้นที่จอดไม่ว่างเลยในชั้นต่ำ
ๆ
ผมจึงต้องขับรถไปจอดเกือบชั้นสูงสุดของที่จอดรถ
และรู้สึกว่าในชั้นนั้นเงียบ
และไม่มียามหรือผู้คนอยู่บริเวณนั้นเลย
ขณะที่ขับรถไปจอดข้าง ๆ
รถเบ้นซ์คนหนึ่ง
ทันไดนั้นเสียงไซเรนป้องกันขโมยของรถเบ้นซ์คันนั้นก็ดังขึ้น
และดังเช่นนั้นตลอดเวลา
เมื่อผมลงมาสำรวจว่ามีอะไรเกิดขึ้น
คิดว่าไปเฉี่ยวชนรถหรือเปล่า
สำรวจดูแล้วก็ไม่ใช่
จอดก็ไม่ได้ชิดกันแทบจะเรียกว่าห่างก็ว่าได้
ผมก็เลยยืนดูพักหนึ่งเผื่อเจ้าของรถจะมาปิดเสียง
15
นาทีแล้วยังไม่มีวี่แววใครจะขึ้นมาเลย
แถวนั้นยามก็ไม่มีคงจะอยู่ไกลเกินที่จะได้ยินเสียง
ผมจึงต้องลงไปบอกยามเองที่ชั้นเกือบล่างสุด
ท้ายสุดผมคิดว่ายามคงต้องไปแจ้งประชาสัมพันธ์ของห้างไห้เรียกตามหาเจ้าของรถต่อไป
ไซเรนรถค้นนั้นดังอยู่ร่วมชั่วโมง
ผมจึงคิดว่า
บางทีถ้าเราอยู่ไกลเกินกว่าเราจะได้ยิน
เครื่องกันขโมยชนิดไหนก็ป้องกันไม่ได้
ถ้าหากเป็นขโมยมาทุบกระจกเอาของมีค่าในรถคงจะได้ไปแล้วแม้ไซเรนจะดังอยู่
และเดี๋ยวนี้ขโมยจ้องจะเอาของในรถมากกว่าจะขโมยตัวรถและง่ายกว่าด้วย
เหตุการนั้นทำให้ผมเกิดไอเดีย
ถ้าหากเราจะซื้อเครื่องโทรศัพท์มือถือรุ่นใหม่จอสีอีกซักเครื่อง
เพราะขืนยังใช้จอขาวดำอยู่เดี๋ยวคนอื่นเห็นจะหาว่าเราเชย
แล้วเครื่องเก่าจะเอาไปไว้ไหนเล่า
ขายก็คงไม่ได้ราคาเท่าไหร่
เอามาทำโครงงานนี้ดีกว่า
ใช้มือถือ NOKIA เก่า
ๆ ให้เป็นยาม
หลักการทำงาน
ซ่อนเครื่องโทรศัพท์มือถือตัวเก่าไว้ในรถ
พร้อมกับอุปกรณ์อีเลคทรอนิคส์
เมื่อมีเหตุการณ์ เช่น
ไซเรนกันขโมยเราดัง,เสียงสตาร์ทเครื่องยนต์,
มีการทุบกระจก,มีการขูดสีรถ,งัดแงะรถ,หรือมีการถูกเฉี่ยวชน
อุปกรณ์อีเลคทรอนิคส์ก็จะไปควบคุมให้เครื่องโทรศัพท์มือถือที่อยู่ในรถส่ง
SMS ไปบอกเราว่ามีเหตุการอะไรเกิดขึ้นกับรถเรา
อย่าง
ๆ น้อย ๆ
ก็ทำให้เรารู้ได้เร็วก่อนที่เหตุจะสายเกินไป
และที่สำคัญเครื่องโทรศัพท์ไม่เพียงจะส่ง
SMS ไปบอกเหตุการเราอย่างเดียว
แต่ยังบอกตำแหน่งของตัวรถในขณะนั้นว่าอยู่ที่บริเวณใดได้ด้วย
โดยส่งรหัส Cell Site
ที่เครื่องโทรศัพท์เครื่องนั้นอยู่ใกล้
แม้ว่าจะไม่แม่นยำเหมือน
GPS (1 - 10 เมตร) แต่ก็ทำให้เรารู้ได้ว่าตัวรถเราอยู่ในรัศมีของ
Cell Site ที่มันใช้นั้น (ระหว่าง 1
- 5 ก.ม.)
สาเหตุที่เลือกใช้และข้อดีของ
การส่ง SMS
อุปกรณ์ที่ต้องใช้โครงงานนี้
1 - ตัวตรวจจับการสั่นสะเทือนของตัวถังรถ
แท้จริงก็คือ
ตัวคอนเดนเซอร์
ไมโครโฟนเราดี ๆ นั่นเอง
แต่ต้องหันปากให้แนบกับตัวถังรถ
2 - ตัวไมโครคอนโทรลเลอร์
+ การเขียนโปรแกรม
3 - เครื่องโทรศัพท์มือถือรุ่นเก่ายี่ห้อ
NOKIA ( DCT3
ที่เลือกรุ่นนี้เพราะหัวสายคอนเนคเตอร์มีขนาดใหญ่ใส่อุปกรณ์เข้าในง่าย)
4 - หัวคอนเนคเตอร์
( ตัดมาจากสายดาต้าลิ้งที่มีขายทั่วไป
)
ลองมาดูตัวต้นแบบกันก่อนว่าเป็นเช่นไร

สังเกตุปากไมโครโฟน
เวลาซ่อนไว้ในรถต้องหันปากเข้าแนบกับตัวถังรถ

สำหรับเครื่องต้องมีซิมการ์ดที่สามารถใช้การได้
ถ้ามีเหตุการทำให้ตัวถังรถมีการสั่นสะเทือน
ตัวโปรแกรมที่อยู่ในไมโครคอนโทรลเลอร์
จะทำการวิเคราะห์การสั่นสะเทือนก่อนด้วยวิธีทาง
Spectum ก่อนว่าเป็นเหตุการจริงจึงจะทำการส่ง
SMS ฉนั้นเสียงรบกวนรอบ ๆ
ข้างนั้น
ถ้าโปรแกรมวิเคราะห์
Spectum ดูแล้ว
ไม่ใกล้เคียงกับข้อมูลของเหตุการจริงก็จะไม่มีการส่ง
SMS เพราะถือว่าเป็น
เสียงรบกวนรอบ ๆ ข้าง
และอย่าลืมว่าการ
ส่ง SMS นั้นต้องอาศัย สัญญาณ
ให้บริการของสถานีเครือข่าย
และเสียค่าบริการ
ควรสำรวจดูก่อนว่าตำแหน่งที่เครื่องโทรศัพท์ซ่อนอยู่มีสัญญาณหรือไม่
การลงอุปกรณ์อีเลคทรอนิคส์เข้าไปไว้ในตัวคอนเนคเตอร์

จะเข้าไปทั้งหมดได้ไม่ได้
อยู่ที่ฝีมือแล้วละครับ
เสร็จแล้วใส่เข้าไปแทนแบตเตอรี่
แล้วเปิดเครื่อง

วิธีใช้งาน
ตัวโปรแกรม
จะอ่าน
เบอร์ที่เราต้องการจะให้ส่ง
SMS ไปให้
ซึ่งถูกบันทึกไว้ก่อนแล้วในซิมการ์ด
ส่วน
เบอร์ของศูนย์ SMS มีอยู่ใน
ซิมการ์ดตามเครือข่ายของค่าย
นั้น ๆ อยู่แล้ว
ดังนั้น
ถ้าจะให้ส่ง SMS
ไปหาเบอร์ใดต้องทำการบันทึกเบอร์ก่อน
ตัวโปรแกรมจะถือว่าเบอร์ที่ถูกบันทึกครั้งล่าสุดเป็นเบอร์ที่กำหนด
ให้เป็นเป้าหมายในการส่ง
SMS
แล้วตั้งชื่อภาษาใดก็ได้
4 ตัวอักษร แล้วตาม ตัวแลขอีก
3 หลัก 100 - 999
ตัวเลขนี้หมายถึงการกำหนดความไวในการรับการสั่นสะเทือน
100
= ความไวสูงสุด 999 =
ความไวต่ำสุดคือเหมือนกับปิดตัวตรวจจับการสั่นสะเทือน
แต่ยังสามารถส่ง SMS
จากเครื่อง
มาเข้าเครื่องนี้เพื่อเปลี่ยนความไวได้อีก
โดยส่ง SMS ดังนี้ Lxxx ( Level=xxx ) คือความไว 100 - 999
ตัวอย่าง
ถ้าส่ง SMS ข้อความ L250
หมายถึงให้ปรับความไวไปที่
250
ถ้าส่ง SMS
ข้อความ L999
หมายถึงให้ปรับความไวไปที่
999 หรือเท่ากับปิดการทำงาน
ดังนั้นขึ้นอยู่ว่าตัวตรวจจับการสั่นสะเทือนติดตั้งไว้ที่ใด
เช่นถ้าติดตั้งไว้ในต้วรถมีเสียงรบกวนเข้าน้อย
ควรกำหนดให้ความไวสูง
ถ้าติดตั้งไว้ในห้องเครื่องยนต์จะมีการสั่นสะเทือนสูงอยู่แล้วควรกำหนดให้
มีความไวต่ำ
ถ้ากำหนดผิดก็ไม่เป็นไร
เพียงแต่ตัวโปรแกรมต้องคอยรับสัญญาณรบกวนรอบข้างมาวิเคราะห์บ่อย
ๆ
ทำให้เสียเวลาในการเฝ้าระวังเหตุการจริง

สังเกตุ
ตัวเลข 3
หลักสุดท้ายของชื่อ
เป็นการกำหนดความไวสูงสุดในการตรวจจับการสั่นสะเทือน
เมื่อกด
ตกลง แล้ว
ก็ใส่เบอร์เป้าหมายในการส่ง
SMS ตามปรกติ
เมื่อดูมาถึงตอนนี้
อดไม่ได้ที่จะนำเอาจอ LCD
จากโครงงานที่ 2
มาต่อผนวกเข้ากับโครงงานนี้อีกไม่ได้
กลายเป็นอีก
เวอร์ชั่นหนึ่งเลย
แต่ยัดเข้าไปในตัวคอนเนคเตอร์ไม่ได้
ต้องใช้กล่องเอนกประสงค์มาทำ

มาดูความหมายที่แสดงผลออกมาที่จอ
LCD

บรรทัดที่
1 C=+6618110888 คือเบอร์ของศูนย์ SMS
ของเครือข่าย ค่าย AIS
บรรทัดที่
2 D=(017857154)
คือเบอร์เป้าหมายที่จะให้ส่ง
SMS ไปหา
ได้มาจากเบอร์ล่าสุดที่ได้บันทึกไว้ในซิมการ์ด
บรรทัดที่
3 บอกสถานะขณะนี้
คือพร้อมใช้งาน
ถ้าไม่ได้ต่อเครื่องโทรศัพท์หรือไม่ได้เปิดเครื่องโทรศัพท์จะขึ้น
Try to connect
บรรทัดที่ 4 รหัส
LAC ของ Cell Site ขณะนี้
บรรทัดที่
5 รหัส CID ของ Cell Site ขณะนี้
ซึ่งจะหมายถึง Intervech3
ที่ขึ้นที่จอของเครื่องโทรศัพท์มือถือ
บรรทัดที่
6 R=100
คือค่าที่เรากำหนดความไวในการตรวจจับการสั่นสะเทือน
S=31
การสั่นสะเทือนที่รับได้ขณะนี้
(31=ไม่มีการสั่นสะเทือน)
วิธีการติดตั้ง

ตัวคอนเนคเตอร์ใส่เข้าไปแทนแบตเตอรี่
ซึ่งจะได้รับไฟ 4 โวลท์
จากวงจรจ่ายไฟในกล่อง
และส่ายสัญญาณดาต้าก็มาจาก
ตัวไมโครคอนโทรลเลอร์ที่อยู่ในกล่องด้วย
ถ้าสวิชต์ทดสอบอยู่ที่ตำแหน่งทดสอบ
ถ้ามีเหตุการก็จะไม่มีการส่ง
SMS ออกไปจริง
แต่จะแสดงผลที่จอของกล่องเอง

ถ้าหากเราจะติดตั้งซ่อนไว้ที่ส่วนของคอนโซลหน้า
ตัวตรวจจับการสั่นสะเทือนก็แปะไว้ที่โลหะโคนพวงมาลัยได้

ถ้าติดตั้งซ่อนไว้ที่
ท้ายรถ
ก็แปะตัวตรวจจับการสั่นสะเทือนที่
ๆ เป็นตัวถัง
และอย่าลืมกำหนดค่าความไวให้มาก
ๆ หน่อย
ในการทดสอบ
โดยติดตั้งซ่อนไว้ที่ท้ายรถ
แล้วใช้เหล็กขูดโคลนที่ใต้ท้องรถออก
โดยขูดลากยาวประมาณ 1
วินาที
ตัวตรวจจับการสั่นสะเทือน
วิเคราะห์ได้และ ส่ง SMS
ไปยังเครื่องเป้าหมายดังนี้

SMS
ที่ได้รับมีความหมายดังนี้
บรรทัดที่
1 คือข้อความเตือน Security Alert
บรรทัดที่
2 ตัวเลข 3 หลัก จำนวน 3 ชุด
คือระดับความแรงภายใน 1
วินาที ต้น ๆ วินาที =127 กลาง 127
ปลาย 632
แสดงถึง
การขูดในช่วงแรกเบาจนถึงกลาง
ๆ และปลาย ๆ เร็วและแรง
นั่นคือลักษณะของการขูดรถ
ซึ่งพอเดาได้
ถ้าเป็นการสตาร์ทรถ
ช่วงแรกจะแรงมาก
แล้วลดความแรงลงในช่วงปลาย
เป็นต้น
บรรทัดที่ 3
เป็นข้อมูลตำแหน่ง Cell Site
ที่ใกล้ที่สุดและใช้อยู่ขณะนี้
ข้อนี้เป็นประโยชน์มากในกรณี
ถ้ามีเหตุการเกิดขึ้นและเราไม่สามารถกลับมาที่เกิดเหตุได้ทันการ
และตัวรถเคลื่อนตัวออกไปแล้ว
ในกรณีนี้ตัวตรวจจับการสั่นสะเทือนจะได้รับการสั่นสะเทือนตลอดเวลา
เมื่อตัวโปรแกรมวิเคราะห์ว่าเป็นการสั่นสะเทือนตลอดเวลา
เหมือนรถวิ่งอยู่
ก็จะทำการส่ง SMS ออกมาทุก ๆ 1
นาที
พร้อมกับสถานที่
Cell Site ที่อยู่ใกล้ขณะนั้น
ทำให้เรารู้ว่า
ขณะนี้ตัวรถเคลื่อนตัวไปทางใด
ถ้ามาถึงขั้นนี้คงต้องยอมเสียเงินค่า
SMS แล้วหละ (ปัจจุบันครั้งละ 1
บาท)
เพื่อจะได้รู้ว่ารถเราอยู่ที่ไหนขณะนี้
แต่ถ้าเราไม่ต้องการให้ส่ง
SMS มาทุก ๆ 1 นาที ก็สามารถ ส่ง
SMS ไปปิดการทำงาน (L999)
แล้วส่ง
SMS ไปสอบถามว่าอยู่ที่ใหนเป็นระยะ
ๆ ก็ได้ โดยส่งคำสั่ง W ( Where )
เครื่องก็จะส่ง
SMS ตอบกลับมาว่าอยู่ที่ใด
ภายใน 15 วินาที
ส่วนการทดสอบว่าใช้กับเครื่อง
NOKIA รุ่นใดได้บ้าง
เท่าที่มีหัวคอนเนคเตอร์ที่มีขายตามท้องตลาด
DCT3 ทุกรุ่น
5110-6110-3210-3310-3330-3350-8210-8250-8850-2100-3650
และ
DCT4 8310-6250 ต้องใช้หัวคอนเนคเตอร์ที่มีถาดซิมอยู่ในตัวเพราะว่าต้องถอดถาดซิมที่ตัวเครื่องออก
คิดว่าตัวโปรแกรมรองรับทุกรุ่นของ
NOKIA ตั้งแต่จอขาวดำถึงจอสี
แต่คงไม่มีใครจะทิ้งเครื่องจอสีไว้ในรถเลยไม่ได้ทดลอง
ก่อนที่จะศึกษาเกี่ยวกับวงจร
และแนวทางการเขียนโปรแกรม
มาดูเครื่องต้นแบบกันก่อน

รูปวงจร

Download
Hex file for ATMEGA8
ถ้าใส่เข้ากับกล่องเอนกประสงค์ยากไป
ออกแบบลายแผ่นปริ้น
แล้วใส่ลงไปในโครงของเครื่องโทรศัพท์ไนเกีย
3310 อย่างนี้ดีกว่า

ลายปริ้น

ใช้
IC AVR ATMEGA8
แบบติดตั้งผิวหน้าแทน
จะได้มีขนาดเล็กลง
ราคาก็พอ ๆ กัน

เมื่อประกอบเสร็จ
ต่อสายเข้ากับแจ็คท้ายเครื่อง
ไมค์ - ชาร์จ - กราวด์

ตั้งชื่อโครงงานที่สำเร็จนี้ว่า
Alert Rider เวอร์ชั่น 1.0

โครงงานที่ 2
โครงงานและการเขียนโปรแกรมสำหรับ
Microcontroller ตระกูล PIC และ MCS51
ในการศึกษาและพัฒนาระบบ
Microcontroller
ในส่วนของอุปกรณ์ในการแสดงผลนั้นมีหลายแบบไม่ว่าจะเป็น
หลอด LED,LED 7
Segment หรือจอ LCD
แม้ว่าจอ
LCD
จะมีประโยชน์และมีประสิทธิภาพมาก
ใช้พลังงานน้อย
และสามารถแสดงผลระเอียดทั้งตัวหนังสือและรูปภาพ
แต่ก็มีปัญหาในเรื่องของราคาแพงจนทำให้ต้นทุนของผลงานค่อนข้างสูง
ยกตัวอย่างเช่น จอ LCD
ที่แสดงผลแบบตัวหนังสือ
อย่างเดียวขนาดแค่ครึ่งนิ้วยังมีราคาเกิน
500 บาทเข้าไปแล้ว
ถ้าเป็นแบบแสดงผลรูปภาพได้ไม่ต้องพูดถึง
ราคาเกิน 1000
อยู่แล้ว
และถ้าผลงานไม่ดีจริงและราคาย่อม
ๆ ได้กำไรน้อย
จะทำให้เราไม่อยากจะลงทุนหรือสร้างผลงานออกมาขายนัก
แต่ในปัจจุบันลองหันมาดูอุปกรณ์อะไหล่ของเครื่องโทรศัพท์มือถือดูซิครับ
ราคาถูกอย่างไม่น่าเชื่อ
เช่นของรุ่น โนเกีย 3310
ตัว Buzzer
ราคาตัวละ 10 บาท
ฝาหน้า+หลัง
50 บาท
พวก
แจ็ค คอนเน็คเตอร์ต่าง ๆ
ตัวละไม่เกิน 20 บาท
แบตเตอรี่
ลิเธี่ยม อย่างดีก้อนละ
ไม่ถึง 200 บาท
จอ
LCD
แบบแสดงรูปภาพอย่างดีราคา
ไม่เกิน 250 บาท

นี่เป็นราคาขายปลีก
และยังมีอุปกรณ์อื่น ๆ เช่น
หูฟัง ไมค์ บอร์ดี้
ล้วนแล้วราคาถูกมาก
และยังมีเกลื่อนล้นตลาดอยู่ในขณะนี้
จึงมีแนวคิดว่า
ถ้าเรานำอุปกรณ์เหล่านี้มาเขียนมาสร้างเป็นโครงงานเพื่อเป็นแนวทางให้เพื่อนนักอีเลคทรอนิคส์เกิดไอเดีย
มาสร้างสรรผลงานหรือศึกษาพัฒนาผลงานของตน
คงจะเป็นประโยชน์ไม่มากก็น้อย
ผมจะพยายามเอาอุปกรณ์อะไหล่
โทรศัพท์เหล่านี้มาสร้างเป็นโครงงานสัก
เดือนหรือสองเดือน อย่าง
แล้วแต่เวลาว่างหรือเกิดไอเดีย
มาเริ่มที่โครงงานแรกก่อน
โครงงานที่
1 หยิบจอ LCD 3310 มาต่อกับ PIC16F876-20
รูปวงจรโครงงานที่
2

รูปภาพเมื่อทำการจ่ายไฟเข้าวงจรทำงาน

สำหรับตัวโปรแกรมผมจะใช้ภาษา
C เพราะง่ายต่อการอธิบาย
////////////////////////////////////////////////////////////////////////////
//
โปรแกรมย่อย
และตัวอย่างเมนโปรแกรม
เพื่อติดต่อและแสดงผลออกจอ
LCD โนเกีย 3310
/////////////////////////////////////////////////////////////////////////////
#include <16f876.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,PUT
#use delay(clock=20000000) //one instruction=0.2us
#byte userport =0x06 // อ้างตำแหน่ง Port B 0x06
#byte tris_userport =0x86 //อ้างตำแหน่ง Tris Port B
0x86
// ต่อขาจอ NOKIA 3310 LCD ใช้ 5
ขาในการติดต่อ sclk-sda-dc-cs-res
#bit nok_sclk =userport.6 // ขา RB6
#bit nok_sda =userport.5 // ขา RB5
#bit nok_dc =userport.4 // ขา RB4
#bit nok_cs =userport.3 // ขา RB3
#bit nok_res =userport.2 // ขา RB2
//--------------------------------ประกาศชื่อโปรแกรมย่อย
void nokia_init(void); //ขอติดต่อกับจอ
LCD ครั้งแรกครั้งเดียว
void nokia_write_command(char bytefornokia_command); //ส่งคำสั่งไปยัง
LCD
void nokia_write_data(char bytefornokia_data); //
ส่งข้อมูลไปยัง LCD
void nokia_write_dorc(char bytefornokia); // ส่ง 1
อักษรไปยัง LCD
void nokia_gotoxy(byte xnokia, byte ynokia); //ตั้งตำแหน่ง
คอลั่ม-บรรทัด 14x6
void nokia_printchar(byte cvar); //พิมพ์ชุดตัวหนังสือออกจอ
LCD
void nokia_clean_ddram(void); //ล้างหน่วยความจำของจอ=ล้างจอ
LCD
void table_to_nokialcd(void); //อ่านชุดรูปภาพตัวอักษรที่ออกแบบไว้แล้วไปยังจอ
LCD
char char_row,charsel,charpos,chardata; //ตัวแปรต่าง
ๆที่ใช้ในโปรแกรมย่อย
int16 ddram;
//ASCII table for NOKIA LCD: 96 rows * 5 bytes= 480 bytes
ชุดรูปภาพตัวอักษรที่ออกแบบไว้แล้ว
ตัวละ 5 ไบท์
BYTE CONST TABLE5 [240]={0x00,0x00,0x00,0x00,0x00, // 20 space
เริ่มที่ตัวอักษรเว้นวัก
0x00,0x00,0x5f,0x00,0x00, // 21 !
0x00,0x07,0x00,0x07,0x00, // 22 "
0x14,0x7f,0x14,0x7f,0x14, // 23 #
0x24,0x2a,0x7f,0x2a,0x12, // 24 $
0x23,0x13,0x08,0x64,0x62, // 25 %
0x36,0x49,0x55,0x22,0x50, // 26 &
0x00,0x05,0x03,0x00,0x00, // 27 '
0x00,0x1c,0x22,0x41,0x00, // 28 (
0x00,0x41,0x22,0x1c,0x00, // 29 )
0x14,0x08,0x3e,0x08,0x14, // 2a *
0x08,0x08,0x3e,0x08,0x08, // 2b +
0x00,0x50,0x30,0x00,0x00, // 2c ,
0x08,0x08,0x08,0x08,0x08, // 2d -
0x00,0x60,0x60,0x00,0x00, // 2e .
0x20,0x10,0x08,0x04,0x02, // 2f /
0x3e,0x51,0x49,0x45,0x3e, // 30 0
0x00,0x42,0x7f,0x40,0x00, // 31 1
0x42,0x61,0x51,0x49,0x46, // 32 2
0x21,0x41,0x45,0x4b,0x31, // 33 3
0x18,0x14,0x12,0x7f,0x10, // 34 4
0x27,0x45,0x45,0x45,0x39, // 35 5
0x3c,0x4a,0x49,0x49,0x30, // 36 6
0x01,0x71,0x09,0x05,0x03, // 37 7
0x36,0x49,0x49,0x49,0x36, // 38 8
0x06,0x49,0x49,0x29,0x1e, // 39 9
0x00,0x36,0x36,0x00,0x00, // 3a :
0x00,0x56,0x36,0x00,0x00, // 3b ;
0x08,0x14,0x22,0x41,0x00, // 3c <
0x14,0x14,0x14,0x14,0x14, // 3d =
0x00,0x41,0x22,0x14,0x08, // 3e >
0x02,0x01,0x51,0x09,0x06, // 3f ?
0x32,0x49,0x79,0x41,0x3e, // 40 @
0x7e,0x11,0x11,0x11,0x7e, // 41 A
0x7f,0x49,0x49,0x49,0x36, // 42 B
0x3e,0x41,0x41,0x41,0x22, // 43 C
0x7f,0x41,0x41,0x22,0x1c, // 44 D
0x7f,0x49,0x49,0x49,0x41, // 45 E
0x7f,0x09,0x09,0x09,0x01, // 46 F
0x3e,0x41,0x49,0x49,0x7a, // 47 G
0x7f,0x08,0x08,0x08,0x7f, // 48 H
0x00,0x41,0x7f,0x41,0x00, // 49 I
0x20,0x40,0x41,0x3f,0x01, // 4a J
0x7f,0x08,0x14,0x22,0x41, // 4b K
0x7f,0x40,0x40,0x40,0x40, // 4c L
0x7f,0x02,0x0c,0x02,0x7f, // 4d M
0x7f,0x04,0x08,0x10,0x7f, // 4e N
0x3e,0x41,0x41,0x41,0x3e}; // 4f O
BYTE CONST TABLE6 [240]={0x7f,0x09,0x09,0x09,0x06, // 50 P
0x3e,0x41,0x51,0x21,0x5e, // 51 Q
0x7f,0x09,0x19,0x29,0x46, // 52 R
0x46,0x49,0x49,0x49,0x31, // 53 S
0x01,0x01,0x7f,0x01,0x01, // 54 T
0x3f,0x40,0x40,0x40,0x3f, // 55 U
0x1f,0x20,0x40,0x20,0x1f, // 56 V
0x3f,0x40,0x38,0x40,0x3f, // 57 W
0x63,0x14,0x08,0x14,0x63, // 58 X
0x07,0x08,0x70,0x08,0x07, // 59 Y
0x61,0x51,0x49,0x45,0x43, // 5a Z
0x00,0x7f,0x41,0x41,0x00, // 5b [
0x02,0x04,0x08,0x10,0x20, // 5c
0x00,0x41,0x41,0x7f,0x00, // 5d
0x04,0x02,0x01,0x02,0x04, // 5e
0x40,0x40,0x40,0x40,0x40, // 5f
0x00,0x01,0x02,0x04,0x00, // 60
0x20,0x54,0x54,0x54,0x78, // 61 a
0x7f,0x48,0x44,0x44,0x38, // 62 b
0x38,0x44,0x44,0x44,0x20, // 63 c
0x38,0x44,0x44,0x48,0x7f, // 64 d
0x38,0x54,0x54,0x54,0x18, // 65 e
0x08,0x7e,0x09,0x01,0x02, // 66 f
0x0c,0x52,0x52,0x52,0x3e, // 67 g
0x7f,0x08,0x04,0x04,0x78, // 68 h
0x00,0x44,0x7d,0x40,0x00, // 69 i
0x20,0x40,0x44,0x3d,0x00, // 6a j
0x7f,0x10,0x28,0x44,0x00, // 6b k
0x00,0x41,0x7f,0x40,0x00, // 6c l
0x7c,0x04,0x18,0x04,0x78, // 6d m
0x7c,0x08,0x04,0x04,0x78, // 6e n
0x38,0x44,0x44,0x44,0x38, // 6f o
0x7c,0x14,0x14,0x14,0x08, // 70 p
0x08,0x14,0x14,0x18,0x7c, // 71 q
0x7c,0x08,0x04,0x04,0x08, // 72 r
0x48,0x54,0x54,0x54,0x20, // 73 s
0x04,0x3f,0x44,0x40,0x20, // 74 t
0x3c,0x40,0x40,0x20,0x7c, // 75 u
0x1c,0x20,0x40,0x20,0x1c, // 76 v
0x3c,0x40,0x30,0x40,0x3c, // 77 w
0x44,0x28,0x10,0x28,0x44, // 78 x
0x0c,0x50,0x50,0x50,0x3c, // 79 y
0x44,0x64,0x54,0x4c,0x44, // 7a z
0x00,0x08,0x36,0x41,0x00, // 7b
0x00,0x00,0x7f,0x00,0x00, // 7c
0x00,0x41,0x36,0x08,0x00, // 7d
0x10,0x08,0x08,0x10,0x08, // 7e
0x78,0x46,0x41,0x46,0x78}; // 7f
////////////////////////////////////////////////////////////////////
void nokia_init(void)
{
tris_userport =0x83; // iooo ooii
delay_us(200);
nok_dc=1; // bytes are stored in the display data ram,
// address counter, incremented automatically
nok_cs=1; // chip disabled
delay_us(200);
nok_res=0; // reset chip during 250ms
delay_ms(10); // works with less.....
nok_res=1;
nokia_write_command(0x21); // set extins extended instruction set
nokia_write_command(0xC4); // Vop
ค่าปรับความเข้มของจอ 0xc4
ถ้าน้อยกว่านี้จางมากกว่าเข้ม
nokia_write_command(0x13); // bias
nokia_write_command(0x20); // horizontal mode from left to right, X axe are incremented automatically
//, 0x22 for vertical addressing ,back on normal instruction set too
nokia_write_command(0x09); // all on
delay_ms(50);
nokia_clean_ddram(); // reset DDRAM, otherwise the lcd is blurred with random pixels
delay_ms(10);
nokia_write_command(0x08); // mod control blank change (all off)
delay_ms(10);
nokia_write_command(0x0c); // mod control normal change
tris_userport=0xF3; // iiii ooii
}
///////////////////////////////////////////////////////////
void nokia_clean_ddram(void)
{
nokia_gotoxy(0,0); // 84*6=504 clear LCD
for (ddram=504;ddram>0;ddram--){nokia_write_data(0x00);}
}
//////////////////////////////////////////////////////////
void nokia_write_command(char bytefornokia_command)
{
tris_userport =0x83; // iooo ooii
nok_dc=0; // byte is a command it is read with the eight SCLK pulse
nok_cs=0; // chip enabled
nokia_write_dorc(bytefornokia_command);
nok_cs=1; // chip disabled
tris_userport =0xF3; // iiii ooii
}
/////////////////////////////////////////////////////////
void nokia_write_data(char bytefornokia_data)
{
tris_userport =0x83; // iooo ooii
nok_dc=1;
nok_cs=0; // chip enabled
nokia_write_dorc(bytefornokia_data);
nok_cs=1; // chip disabled
tris_userport =0xF3; // iiii oo11
}
////////////////////////////////////////////////////////
void nokia_write_dorc(char bytefornokia) // serial write data or command subroutine
{
char caa;
for (caa=8;caa>0;caa--)
{
nok_sclk=0;
delay_us(2);
if ((bytefornokia&0x80)==0){nok_sda=0;}
else {nok_sda=1;}
nok_sclk=1;
bytefornokia=bytefornokia<<1;
}
}
////////////////////////////////////////////////////////
void nokia_gotoxy(byte xnokia, byte ynokia) // Nokia LCD 3310 Position cursor
{
nokia_write_command(0x40|(ynokia&0x07)); // Y axe initialisation: 0100 0yyy
nokia_write_command(0x80|(xnokia&0x7f)); // X axe initialisation: 1xxx xxxx
}
////////////////////////////////////////////////////////
void nokia_printchar(byte cvar) // Write 1 character to LCD
{
charsel=cvar;
table_to_nokialcd();
}
////////////////////////////////////////////////////////
void table_to_nokialcd(void) // extract ascii from tables & write to LCD
{
if (charsel<0x20)return;
if (charsel>0x7f)return;
for (char_row=0;char_row<5;char_row++)
{ // 5 bytes
if (charsel<0x50)
{
charpos=((charsel-0x20)*5);
chardata=TABLE5[(charpos+char_row)];
} // use TABLE5
if (charsel>0x4f)
{
charpos=((charsel-0x50)*5);
chardata=TABLE6[(charpos+char_row)];
} // use TABLE6
nokia_write_data(chardata); // send data to nokia
}
nokia_write_data(0x00); // 1 byte (always blank)
}
//////////////////////////////////////////////////////////
//
เริ่มต้วอย่างโปรแกรม
//////////////////////////////////////////////////////////
void main()
{
nokia_init();
// ติดต่อจอครั้งแรกก่อน
delay_ms(100); // รอ 100 ms
nokia_gotoxy(0,1); // ตั้งตำแหน่ง 0=เริ่มคอลั่ม
1: 1= บรรทัดที่ 2
nokia_printchar(" Testing LCD"); //พิมพ์ชุดอักษรนี้ไปออกจอ
nokia_gotoxy(0,3);
// ตั้งตำแหน่งคอลั่มที่1
บรรทัดที่ 4
nokia_printchar(" Hello world"); //
พิมพ์ชุดอักษรนี้ไปออกจอ
while(1)
{
// Stop หยุดอยู่เฉย ๆ
}
}
/////////////////////// the end !! ////////////////////////
ดูดาต้าชีตของจอ
LCD โนเกีย 3310

ตัวอย่างโปรแกรม
Stand Alone Frequency Counter
#include <16f876.h>
#fuses HS,NOWDT,PROTECT,NOLVP,NOBROWNOUT,PUT
#use delay(clock=20000000) //one instruction=0.2us
#use rs232(baud=9600, xmit=PIN_c6, rcv=PIN_c7)
#byte userport =0x06 //b
// NOKIA_LCD // **************************************************************************
#bit nok_sclk =userport.6 // RB6
#bit nok_sda =userport.5 // RB5
#bit nok_dc =userport.4 // RB4
#bit nok_cs =userport.3 // RB3
#bit nok_res =userport.2 // RB2
#bit t1_overflow=0x0C.0
// #bit t1_overflow=0xF9E.0 (PIC18, Reminder)
//--------------------------------------prototypes
void nokia_init(void);
void nokia_write_command(char bytefornokia_command);
void nokia_write_data(char bytefornokia_data);
void nokia_write_dorc(char bytefornokia);
void nokia_gotoxy(byte xnokia, byte ynokia);
void nokia_printchar(byte cvar);
void nokia_clean_ddram(void);
void table_to_nokialcd(void);
char char_row,charsel,charpos,chardata;
int16 ddram;
//ASCII table for NOKIA LCD: 96 rows * 5 bytes= 480 bytes
BYTE CONST TABLE5 [240]={0x00,0x00,0x00,0x00,0x00, // 20 space
0x00,0x00,0x5f,0x00,0x00, // 21 !
0x00,0x07,0x00,0x07,0x00, // 22 "
0x14,0x7f,0x14,0x7f,0x14, // 23 #
0x24,0x2a,0x7f,0x2a,0x12, // 24 $
0x23,0x13,0x08,0x64,0x62, // 25 %
0x36,0x49,0x55,0x22,0x50, // 26 &
0x00,0x05,0x03,0x00,0x00, // 27 '
0x00,0x1c,0x22,0x41,0x00, // 28 (
0x00,0x41,0x22,0x1c,0x00, // 29 )
0x14,0x08,0x3e,0x08,0x14, // 2a *
0x08,0x08,0x3e,0x08,0x08, // 2b +
0x00,0x50,0x30,0x00,0x00, // 2c ,
0x08,0x08,0x08,0x08,0x08, // 2d -
0x00,0x60,0x60,0x00,0x00, // 2e .
0x20,0x10,0x08,0x04,0x02, // 2f /
0x3e,0x51,0x49,0x45,0x3e, // 30 0
0x00,0x42,0x7f,0x40,0x00, // 31 1
0x42,0x61,0x51,0x49,0x46, // 32 2
0x21,0x41,0x45,0x4b,0x31, // 33 3
0x18,0x14,0x12,0x7f,0x10, // 34 4
0x27,0x45,0x45,0x45,0x39, // 35 5
0x3c,0x4a,0x49,0x49,0x30, // 36 6
0x01,0x71,0x09,0x05,0x03, // 37 7
0x36,0x49,0x49,0x49,0x36, // 38 8
0x06,0x49,0x49,0x29,0x1e, // 39 9
0x00,0x36,0x36,0x00,0x00, // 3a :
0x00,0x56,0x36,0x00,0x00, // 3b ;
0x08,0x14,0x22,0x41,0x00, // 3c <
0x14,0x14,0x14,0x14,0x14, // 3d =
0x00,0x41,0x22,0x14,0x08, // 3e >
0x02,0x01,0x51,0x09,0x06, // 3f ?
0x32,0x49,0x79,0x41,0x3e, // 40 @
0x7e,0x11,0x11,0x11,0x7e, // 41 A
0x7f,0x49,0x49,0x49,0x36, // 42 B
0x3e,0x41,0x41,0x41,0x22, // 43 C
0x7f,0x41,0x41,0x22,0x1c, // 44 D
0x7f,0x49,0x49,0x49,0x41, // 45 E
0x7f,0x09,0x09,0x09,0x01, // 46 F
0x3e,0x41,0x49,0x49,0x7a, // 47 G
0x7f,0x08,0x08,0x08,0x7f, // 48 H
0x00,0x41,0x7f,0x41,0x00, // 49 I
0x20,0x40,0x41,0x3f,0x01, // 4a J
0x7f,0x08,0x14,0x22,0x41, // 4b K
0x7f,0x40,0x40,0x40,0x40, // 4c L
0x7f,0x02,0x0c,0x02,0x7f, // 4d M
0x7f,0x04,0x08,0x10,0x7f, // 4e N
0x3e,0x41,0x41,0x41,0x3e}; // 4f O
BYTE CONST TABLE6 [240]={0x7f,0x09,0x09,0x09,0x06, // 50 P
0x3e,0x41,0x51,0x21,0x5e, // 51 Q
0x7f,0x09,0x19,0x29,0x46, // 52 R
0x46,0x49,0x49,0x49,0x31, // 53 S
0x01,0x01,0x7f,0x01,0x01, // 54 T
0x3f,0x40,0x40,0x40,0x3f, // 55 U
0x1f,0x20,0x40,0x20,0x1f, // 56 V
0x3f,0x40,0x38,0x40,0x3f, // 57 W
0x63,0x14,0x08,0x14,0x63, // 58 X
0x07,0x08,0x70,0x08,0x07, // 59 Y
0x61,0x51,0x49,0x45,0x43, // 5a Z
0x00,0x7f,0x41,0x41,0x00, // 5b [
0x02,0x04,0x08,0x10,0x20, // 5c
0x00,0x41,0x41,0x7f,0x00, // 5d
0x04,0x02,0x01,0x02,0x04, // 5e
0x40,0x40,0x40,0x40,0x40, // 5f
0x00,0x01,0x02,0x04,0x00, // 60
0x20,0x54,0x54,0x54,0x78, // 61 a
0x7f,0x48,0x44,0x44,0x38, // 62 b
0x38,0x44,0x44,0x44,0x20, // 63 c
0x38,0x44,0x44,0x48,0x7f, // 64 d
0x38,0x54,0x54,0x54,0x18, // 65 e
0x08,0x7e,0x09,0x01,0x02, // 66 f
0x0c,0x52,0x52,0x52,0x3e, // 67 g
0x7f,0x08,0x04,0x04,0x78, // 68 h
0x00,0x44,0x7d,0x40,0x00, // 69 i
0x20,0x40,0x44,0x3d,0x00, // 6a j
0x7f,0x10,0x28,0x44,0x00, // 6b k
0x00,0x41,0x7f,0x40,0x00, // 6c l
0x7c,0x04,0x18,0x04,0x78, // 6d m
0x7c,0x08,0x04,0x04,0x78, // 6e n
0x38,0x44,0x44,0x44,0x38, // 6f o
0x7c,0x14,0x14,0x14,0x08, // 70 p
0x08,0x14,0x14,0x18,0x7c, // 71 q
0x7c,0x08,0x04,0x04,0x08, // 72 r
0x48,0x54,0x54,0x54,0x20, // 73 s
0x04,0x3f,0x44,0x40,0x20, // 74 t
0x3c,0x40,0x40,0x20,0x7c, // 75 u
0x1c,0x20,0x40,0x20,0x1c, // 76 v
0x3c,0x40,0x30,0x40,0x3c, // 77 w
0x44,0x28,0x10,0x28,0x44, // 78 x
0x0c,0x50,0x50,0x50,0x3c, // 79 y
0x44,0x64,0x54,0x4c,0x44, // 7a z
0x00,0x08,0x36,0x41,0x00, // 7b
0x00,0x00,0x7f,0x00,0x00, // 7c
0x00,0x41,0x36,0x08,0x00, // 7d
0x10,0x08,0x08,0x10,0x08, // 7e
0x78,0x46,0x41,0x46,0x78}; // 7f
////////////////////////////////////////////
BYTE CONST NAME [27]={" Salt & Light Electronics"};
////////////////////////////////////////////
void nokia_init(void)
{
delay_us(200);
nok_dc=1; // bytes are stored in the display data ram,
// address counter, incremented automatically
nok_cs=1; // chip disabled
delay_us(200);
nok_res=0; // reset chip during 250ms
delay_ms(10); // works with less.....
nok_res=1;
nokia_write_command(0x21); // set extins extended instruction set
nokia_write_command(0xC2); // Vop v1: 0xc4 (for nornal LCD)// v2: 0xa0 (for old LCD) = Set contrast
nokia_write_command(0x13); // bias
nokia_write_command(0x20); // horizontal mode from left to right, X axe are incremented automatically
//, 0x22 for vertical addressing ,back on normal instruction set too
nokia_write_command(0x09); // all on
delay_ms(50);
nokia_clean_ddram(); // reset DDRAM, otherwise the lcd is blurred with random pixels
delay_ms(10);
nokia_write_command(0x08); // mod control blank change (all off)
delay_ms(10);
nokia_write_command(0x0c); // mod control normal change
}
//////////////////////////////////////////////////////////////////////////////
void nokia_clean_ddram(void)
{
nokia_gotoxy(0,0); // 84*6=504 fill LCD
for (ddram=504;ddram>0;ddram--){nokia_write_data(0xFF);}
delay_ms(1000);
nokia_gotoxy(0,0); // 84*6=504 clear LCD
for (ddram=504;ddram>0;ddram--){nokia_write_data(0x00);}
}
///////////////////////////////////////////////////////////////////////////////
void nokia_write_command(char bytefornokia_command)
{
nok_dc=0; // byte is a command it is read with the eight SCLK pulse
nok_cs=0; // chip enabled
nokia_write_dorc(bytefornokia_command);
nok_cs=1; // chip disabled
}
/////////////////////////////////////////////////////////////////////////////////
void nokia_write_data(char bytefornokia_data)
{
nok_dc=1;
nok_cs=0; // chip enabled
nokia_write_dorc(bytefornokia_data);
nok_cs=1; // chip disabled
}
//////////////////////////////////////////////////////////////////////////////////
void nokia_write_dorc(char bytefornokia) // serial write data or command subroutine
{
char caa;
for (caa=8;caa>0;caa--)
{
nok_sclk=0;
delay_us(2);
if ((bytefornokia&0x80)==0){nok_sda=0;}
else {nok_sda=1;}
nok_sclk=1;
bytefornokia=bytefornokia<<1;
}
}
//////////////////////////////////////////////////////////////////////////////////
void nokia_gotoxy(byte xnokia, byte ynokia) // Nokia LCD 3310 Position cursor
{
xnokia=xnokia*6;
nokia_write_command(0x40|(ynokia&0x07)); // Y axe initialisation: 0100 0yyy
nokia_write_command(0x80|(xnokia&0x7f)); // X axe initialisation: 1xxx xxxx
}
//////////////////////////////////////////////////////////////////////////////////
void nokia_printchar(byte cvar) // Write 1 character to LCD
{
charsel=cvar;
table_to_nokialcd();
}
//////////////////////////////////////////////////////////////////////////////////
void table_to_nokialcd(void) // extract ascii from tables & write to LCD
{
if (charsel<0x20)return;
if (charsel>0x7f)return;
for (char_row=0;char_row<5;char_row++)
{ // 5 bytes
if (charsel<0x50)
{
charpos=((charsel-0x20)*5);
chardata=TABLE5[(charpos+char_row)];
} // use TABLE5
if (charsel>0x4f)
{
charpos=((charsel-0x50)*5);
chardata=TABLE6[(charpos+char_row)];
} // use TABLE6
nokia_write_data(chardata); // send data to nokia
}
nokia_write_data(0x00); // 1 byte (always blank)
}
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
void main() {
int cycles8, cycles, ltime;
int32 freq;
long freqc_high;
long freqc_low;
SET_TRIS_B(0x83);
SET_TRIS_A(0x00);
nokia_init();
delay_ms(100);
nokia_gotoxy(0,0);
nokia_printchar("--055-241617--");
nokia_gotoxy(0,1);
for (ltime=0;ltime<26;ltime++)
{
nokia_printchar(NAME[ltime]);
delay_ms(100);
}
nokia_gotoxy(0,0);
nokia_printchar(" ");
if( input(PIN_B7) ) {nokia_gotoxy(0,0); nokia_printchar("---Charging---");}
ltime=0;
while (TRUE) {
cycles8=0;
cycles=0;
freqc_high=0;
t1_overflow=0;
set_timer1(0);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
/* ___ wait one second ___ */
while (cycles!=0xFF) { //true=3, false=4
cycles8=0; //1 cycle
//start inner loop
while (cycles8!=0xFF) { //true=3, false=4
if (t1_overflow)//true=2,false=3 //----|
{t1_overflow=0;freqc_high++;OUTPUT_A(freqc_high);}//6+6=12 cycles // |
else // |--+2=14 cycles
{delay_cycles(11);} // +6 //----|
delay_cycles(56); //x -6
cycles8++; //1
///2 cycles to jump to top
//math: end inner loop
//math: total inner loop=((3+8+x+1+2)*255 + 4)*255
//math: if x=62.87781 then inner loops takes 5mil instructions
//math: if x=62 then inner loop takes 4942920, have to fill 57080 cycles
}
delay_cycles(216); //y
cycles++; ///1 cycle
///2 cylces to jump to top
//math: outer=(3+1+y+1+2)*255+4=57080
//math: y=(57080-4)/255)-(3+1+0+0+1+2)
//math: if y=216.827450980392156862745098039216 then outer loop cylces is 57080
//math: if y=216 then outer loop cycles is off by 211 cycles. z=211
}
delay_cycles(211); //z
/* ___ end waiting 1 second ___ */
setup_timer_1(T1_DISABLED); //turn of counter to prevent corruption while grabbing value
if (t1_overflow) //check one last time for overflow
freqc_high++;
freqc_low=get_timer1(); //get timer1 value as the least sign. 16bits of freq counter
freq=make32(freqc_high,freqc_low); //use new make32 function to join lsb and msb
printf("%LU",freq); //and print frequency to rs232
nokia_gotoxy(0,4);
nokia_printchar(" ");
nokia_gotoxy(0,4);
nokia_printchar(" ");
nokia_printchar(NAME[ltime]);
nokia_printchar(" ");
ltime++;
if (ltime>25) ltime=0;
printf(nokia_printchar,"%LU Hz",freq); //and print frequency to Nokia LCD
}
}
/////////////////////// the end !! //////////////////////////////////////////////////